250 lines
14 KiB
HTML
250 lines
14 KiB
HTML
{% extends 'portal_base.html' %}
|
|
{% load static i18n %}
|
|
|
|
{% block title %}{% trans "Agency Dashboard" %} - {% trans "Agency Portal" %}{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="space-y-6">
|
|
|
|
<!-- Header Section -->
|
|
<div class="bg-gradient-to-br from-temple-red to-[#7a1a29] text-white rounded-2xl shadow-lg p-6 md:p-8">
|
|
<div class="flex flex-col md:flex-row md:justify-between md:items-start gap-4">
|
|
<div>
|
|
<div class="flex items-center gap-3 mb-2">
|
|
<div class="w-14 h-14 rounded-xl bg-white/20 backdrop-blur-sm flex items-center justify-center">
|
|
<i data-lucide="building" class="w-8 h-8"></i>
|
|
</div>
|
|
<div>
|
|
<h1 class="text-2xl md:text-3xl font-bold">{% trans "Agency Dashboard" %}</h1>
|
|
<p class="text-white/80">
|
|
{% trans "Welcome back" %}, {{ agency.name }}!
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Statistics Cards -->
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
|
<!-- Total Assignments -->
|
|
<div class="bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden">
|
|
<div class="bg-gradient-to-br from-temple-red to-[#7a1a29] text-white p-4">
|
|
<div class="flex items-center gap-3">
|
|
<i data-lucide="briefcase" class="w-6 h-6"></i>
|
|
<span class="text-sm font-semibold">{% trans "Total Assignments" %}</span>
|
|
</div>
|
|
</div>
|
|
<div class="p-5 text-center">
|
|
<div class="text-3xl font-bold text-temple-red mb-1">{{ total_assignments }}</div>
|
|
<p class="text-xs text-gray-500 uppercase tracking-wide">{% trans "Assigned Jobs" %}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Active Assignments -->
|
|
<div class="bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden">
|
|
<div class="bg-gradient-to-br from-temple-red to-[#7a1a29] text-white p-4">
|
|
<div class="flex items-center gap-3">
|
|
<i data-lucide="check-circle" class="w-6 h-6"></i>
|
|
<span class="text-sm font-semibold">{% trans "Active Assignments" %}</span>
|
|
</div>
|
|
</div>
|
|
<div class="p-5 text-center">
|
|
<div class="text-3xl font-bold text-temple-red mb-1">{{ active_assignments }}</div>
|
|
<p class="text-xs text-gray-500 uppercase tracking-wide">{% trans "In Progress" %}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Total Applications -->
|
|
<div class="bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden">
|
|
<div class="bg-gradient-to-br from-temple-red to-[#7a1a29] text-white p-4">
|
|
<div class="flex items-center gap-3">
|
|
<i data-lucide="users" class="w-6 h-6"></i>
|
|
<span class="text-sm font-semibold">{% trans "Total Applications" %}</span>
|
|
</div>
|
|
</div>
|
|
<div class="p-5 text-center">
|
|
<div class="text-3xl font-bold text-temple-red mb-1">{{ total_applications }}</div>
|
|
<p class="text-xs text-gray-500 uppercase tracking-wide">{% trans "Candidates Submitted" %}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Unread Messages -->
|
|
<div class="bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden">
|
|
<div class="bg-gradient-to-br from-temple-red to-[#7a1a29] text-white p-4">
|
|
<div class="flex items-center gap-3">
|
|
<i data-lucide="mail" class="w-6 h-6"></i>
|
|
<span class="text-sm font-semibold">{% trans "Unread Messages" %}</span>
|
|
</div>
|
|
</div>
|
|
<div class="p-5 text-center">
|
|
<div class="text-3xl font-bold text-yellow-600 mb-1">{{ total_unread_messages }}</div>
|
|
<p class="text-xs text-gray-500 uppercase tracking-wide">{% trans "New Communications" %}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Job Assignments List -->
|
|
<div class="bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden">
|
|
<div class="bg-gradient-to-br from-temple-red to-[#7a1a29] text-white p-5">
|
|
<div class="flex justify-between items-center">
|
|
<div class="flex items-center gap-3">
|
|
<i data-lucide="list-todo" class="w-6 h-6"></i>
|
|
<h2 class="text-lg font-bold">{% trans "Your Job Assignments" %}</h2>
|
|
</div>
|
|
<span class="inline-flex items-center px-3 py-1.5 rounded-lg bg-white/20 backdrop-blur-sm text-sm font-semibold">
|
|
{{ assignment_stats|length }} {% trans "assignments" %}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="p-6">
|
|
{% if assignment_stats %}
|
|
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
|
|
{% for stats in assignment_stats %}
|
|
<div class="border border-gray-200 rounded-xl overflow-hidden hover:border-temple-red transition-all duration-200 hover:shadow-lg">
|
|
<!-- Assignment Header -->
|
|
<div class="bg-temple-cream border-b border-gray-200 p-4">
|
|
<div class="flex justify-between items-start gap-2 mb-2">
|
|
<div class="flex-1">
|
|
<h5 class="font-bold text-temple-dark mb-1">
|
|
<a href="{% url 'agency_portal_assignment_detail' stats.assignment.slug %}"
|
|
class="text-temple-dark hover:text-temple-red transition">
|
|
{{ stats.assignment.job.title }}
|
|
</a>
|
|
</h5>
|
|
<p class="text-sm text-gray-600">
|
|
<i data-lucide="building-2" class="w-3 h-3 inline mr-1"></i>
|
|
{{ stats.assignment.job.department|default:"N/A" }}
|
|
</p>
|
|
</div>
|
|
<div class="shrink-0">
|
|
{% if stats.is_active %}
|
|
<span class="inline-flex items-center px-2.5 py-1 rounded-full text-[10px] font-bold uppercase tracking-wide bg-green-600 text-white">
|
|
{% trans "Active" %}
|
|
</span>
|
|
{% elif stats.assignment.status == 'COMPLETED' %}
|
|
<span class="inline-flex items-center px-2.5 py-1 rounded-full text-[10px] font-bold uppercase tracking-wide bg-gray-600 text-white">
|
|
{% trans "Completed" %}
|
|
</span>
|
|
{% elif stats.assignment.status == 'CANCELLED' %}
|
|
<span class="inline-flex items-center px-2.5 py-1 rounded-full text-[10px] font-bold uppercase tracking-wide bg-red-600 text-white">
|
|
{% trans "Cancelled" %}
|
|
</span>
|
|
{% else %}
|
|
<span class="inline-flex items-center px-2.5 py-1 rounded-full text-[10px] font-bold uppercase tracking-wide bg-yellow-600 text-white">
|
|
{% trans "Expired" %}
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Assignment Body -->
|
|
<div class="p-4 space-y-3">
|
|
<!-- Deadline & Applications -->
|
|
<div class="grid grid-cols-2 gap-3">
|
|
<div>
|
|
<div class="text-xs text-gray-500 mb-1">{% trans "Deadline" %}</div>
|
|
<div class="font-semibold {% if stats.days_remaining <= 3 %}text-red-600{% elif stats.days_remaining <= 7 %}text-yellow-600{% else %}text-green-600{% endif %}">
|
|
{{ stats.assignment.deadline|date:"Y-m-d" }}
|
|
<div class="text-xs text-gray-500 font-normal">
|
|
{% if stats.days_remaining >= 0 %}
|
|
({{ stats.days_remaining }} {% trans "days left" %})
|
|
{% else %}
|
|
({{ stats.days_remaining }} {% trans "days overdue" %})
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="text-xs text-gray-500 mb-1">{% trans "Applications" %}</div>
|
|
<div class="font-semibold">
|
|
{{ stats.application_count }} / {{ stats.assignment.max_candidates }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Progress Bar -->
|
|
<div>
|
|
<div class="flex justify-between text-xs text-gray-500 mb-1">
|
|
<span>{% trans "Submission Progress" %}</span>
|
|
<span>{{ stats.application_count }}/{{ stats.assignment.max_candidates }}</span>
|
|
</div>
|
|
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
|
|
{% with progress=stats.application_count %}
|
|
{% widthratio progress stats.assignment.max_candidates 100 as percentage %}
|
|
<div class="h-full rounded-full transition-all duration-300 {% if percentage >= 90 %}bg-red-600{% elif percentage >= 70 %}bg-yellow-500{% else %}bg-temple-red{% endif %}"
|
|
style="width: {{ percentage }}%"></div>
|
|
{% endwith %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Action Buttons -->
|
|
<div class="flex gap-2 pt-2 border-t border-gray-100">
|
|
{% if stats.can_submit %}
|
|
<a href="{% url 'agency_portal_submit_application_page' stats.assignment.slug %}"
|
|
class="flex-1 inline-flex items-center justify-center gap-2 bg-temple-red hover:bg-[#7a1a29] text-white font-medium px-4 py-2 rounded-lg text-sm transition">
|
|
<i data-lucide="user-plus" class="w-4 h-4"></i>
|
|
{% trans "Submit" %}
|
|
</a>
|
|
{% else %}
|
|
<button class="flex-1 inline-flex items-center justify-center gap-2 bg-gray-200 text-gray-600 font-medium px-4 py-2 rounded-lg text-sm cursor-not-allowed" disabled>
|
|
<i data-lucide="x" class="w-4 h-4"></i>
|
|
{% trans "Closed" %}
|
|
</button>
|
|
{% endif %}
|
|
<a href="{% url 'agency_portal_assignment_detail' stats.assignment.slug %}"
|
|
class="inline-flex items-center justify-center gap-2 border border-temple-red text-temple-red hover:bg-temple-red hover:text-white font-medium px-4 py-2 rounded-lg text-sm transition">
|
|
<i data-lucide="eye" class="w-4 h-4"></i>
|
|
{% trans "View" %}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% include "includes/paginator.html" %}
|
|
{% else %}
|
|
<div class="text-center py-12">
|
|
<i data-lucide="briefcase" class="w-20 h-20 text-gray-300 mx-auto mb-4"></i>
|
|
<h5 class="text-xl font-bold text-gray-900 mb-2">{% trans "No Job Assignments Found" %}</h5>
|
|
<p class="text-gray-500 max-w-md mx-auto">
|
|
{% trans "You don't have any job assignments yet. Please contact the administrator if you expect to have assignments." %}
|
|
</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.card-hover {
|
|
transition: all 0.2s ease-in-out;
|
|
}
|
|
|
|
.card-hover:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
|
}
|
|
|
|
.progress-bar-animated {
|
|
transition: width 0.3s ease;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block customJS %}
|
|
<script>
|
|
lucide.createIcons();
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Auto-refresh for unread messages count
|
|
setInterval(function() {
|
|
// You could implement a lightweight API call here to check for new messages
|
|
// For now, just refresh page every 5 minutes
|
|
location.reload();
|
|
}, 300000); // 5 minutes
|
|
});
|
|
</script>
|
|
{% endblock %} |