532 lines
23 KiB
HTML
532 lines
23 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static i18n %}
|
|
|
|
{% block title %}{{ assignment.agency.name }} - {{ assignment.job.title }} - ATS{% endblock %}
|
|
|
|
{% block customCSS %}
|
|
<style>
|
|
/* KAAT-S UI Variables */
|
|
:root {
|
|
--kaauh-teal: #00636e;
|
|
--kaauh-teal-dark: #004a53;
|
|
--kaauh-border: #eaeff3;
|
|
--kaauh-primary-text: #343a40;
|
|
--kaauh-success: #28a745;
|
|
--kaauh-info: #17a2b8;
|
|
--kaauh-danger: #dc3545;
|
|
--kaauh-warning: #ffc107;
|
|
}
|
|
|
|
.kaauh-card {
|
|
border: 1px solid var(--kaauh-border);
|
|
border-radius: 0.75rem;
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
|
|
background-color: white;
|
|
}
|
|
|
|
.btn-main-action {
|
|
background-color: var(--kaauh-teal);
|
|
border-color: var(--kaauh-teal);
|
|
color: white;
|
|
font-weight: 600;
|
|
transition: all 0.2s ease;
|
|
}
|
|
.btn-main-action:hover {
|
|
background-color: var(--kaauh-teal-dark);
|
|
border-color: var(--kaauh-teal-dark);
|
|
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
|
}
|
|
|
|
.status-badge {
|
|
font-size: 0.75rem;
|
|
padding: 0.3em 0.7em;
|
|
border-radius: 0.35rem;
|
|
font-weight: 700;
|
|
}
|
|
.status-ACTIVE { background-color: var(--kaauh-success); color: white; }
|
|
.status-EXPIRED { background-color: var(--kaauh-danger); color: white; }
|
|
.status-COMPLETED { background-color: var(--kaauh-info); color: white; }
|
|
.status-CANCELLED { background-color: var(--kaauh-warning); color: #856404; }
|
|
|
|
.progress-ring {
|
|
width: 120px;
|
|
height: 120px;
|
|
position: relative;
|
|
}
|
|
|
|
.progress-ring-circle {
|
|
transition: stroke-dashoffset 0.35s;
|
|
transform: rotate(-90deg);
|
|
transform-origin: 50% 50%;
|
|
}
|
|
|
|
.progress-ring-text {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
font-size: 1.5rem;
|
|
font-weight: 700;
|
|
color: var(--kaauh-teal-dark);
|
|
}
|
|
|
|
.message-item {
|
|
border-left: 4px solid var(--kaauh-teal);
|
|
background-color: #f8f9fa;
|
|
padding: 1rem;
|
|
margin-bottom: 1rem;
|
|
border-radius: 0 0.5rem 0.5rem 0;
|
|
}
|
|
|
|
.message-item.unread {
|
|
border-left-color: var(--kaauh-info);
|
|
background-color: #e7f3ff;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid py-4">
|
|
<!-- Header -->
|
|
<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-tasks me-2"></i>
|
|
{{ assignment.agency.name }} - {{ assignment.job.title }}
|
|
</h1>
|
|
<p class="text-muted mb-0">
|
|
{% trans "Assignment Details and Management" %}
|
|
</p>
|
|
</div>
|
|
<div>
|
|
<a href="{% url 'agency_assignment_list' %}" class="btn btn-outline-secondary me-2">
|
|
<i class="fas fa-arrow-left me-1"></i> {% trans "Back to Assignments" %}
|
|
</a>
|
|
<a href="{% url 'agency_assignment_update' assignment.slug %}" class="btn btn-main-action">
|
|
<i class="fas fa-edit me-1"></i> {% trans "Edit Assignment" %}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<!-- Assignment Overview -->
|
|
<div class="col-lg-8">
|
|
<!-- Assignment Details Card -->
|
|
<div class="kaauh-card p-4 mb-4">
|
|
<h5 class="mb-4" style="color: var(--kaauh-teal-dark);">
|
|
<i class="fas fa-info-circle me-2"></i>
|
|
{% trans "Assignment Details" %}
|
|
</h5>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="text-muted small">{% trans "Agency" %}</label>
|
|
<div class="fw-bold">{{ assignment.agency.name }}</div>
|
|
<div class="text-muted small">{{ assignment.agency.contact_person }}</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="text-muted small">{% trans "Job" %}</label>
|
|
<div class="fw-bold">{{ assignment.job.title }}</div>
|
|
<div class="text-muted small">{{ assignment.job.department }}</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="text-muted small">{% trans "Status" %}</label>
|
|
<div>
|
|
<span class="status-badge status-{{ assignment.status }}">
|
|
{{ assignment.get_status_display }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="text-muted small">{% trans "Deadline" %}</label>
|
|
<div class="{% if assignment.is_expired %}text-danger{% else %}text-muted{% endif %}">
|
|
<i class="fas fa-calendar-alt me-1"></i>
|
|
{{ assignment.deadline_date|date:"Y-m-d H:i" }}
|
|
</div>
|
|
{% if assignment.is_expired %}
|
|
<small class="text-danger">
|
|
<i class="fas fa-exclamation-triangle me-1"></i>{% trans "Expired" %}
|
|
</small>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% if assignment.admin_notes %}
|
|
<div class="mt-3 pt-3 border-top">
|
|
<label class="text-muted small">{% trans "Admin Notes" %}</label>
|
|
<div class="text-muted">{{ assignment.admin_notes }}</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
|
|
</div>
|
|
|
|
{% comment %} <div class="kaauh-card shadow-sm mb-4">
|
|
<div class="card-body my-2">
|
|
<h5 class="card-title mb-3 mx-2">
|
|
<i class="fas fa-key me-2 text-warning"></i>
|
|
{% trans "Access Credentials" %}
|
|
</h5>
|
|
|
|
<div class="mb-3 mx-2">
|
|
<label class="form-label text-muted small">{% trans "Login URL" %}</label>
|
|
<div class="input-group">
|
|
<input type="text" readonly value="{{ request.scheme }}://{{ request.get_host }}{% url 'agency_portal_login' %}"
|
|
class="form-control font-monospace" id="loginUrl">
|
|
<button class="btn btn-outline-secondary" type="button" onclick="copyToClipboard('loginUrl')">
|
|
<i class="fas fa-copy"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3 mx-2">
|
|
<label class="form-label text-muted small">{% trans "Access Token" %}</label>
|
|
<div class="input-group">
|
|
<input type="text" readonly value="{{ access_link.unique_token }}"
|
|
class="form-control font-monospace" id="accessToken">
|
|
<button class="btn btn-outline-secondary" type="button" onclick="copyToClipboard('accessToken')">
|
|
<i class="fas fa-copy"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3 mx-2">
|
|
<label class="form-label text-muted small">{% trans "Password" %}</label>
|
|
<div class="input-group">
|
|
<input type="text" readonly value="{{ access_link.access_password }}"
|
|
class="form-control font-monospace" id="accessPassword">
|
|
<button class="btn btn-outline-secondary" type="button" onclick="copyToClipboard('accessPassword')">
|
|
<i class="fas fa-copy"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="alert alert-info mx-2">
|
|
<i class="fas fa-info-circle me-2"></i>
|
|
{% trans "Share these credentials securely with the agency. They can use this information to log in and submit applications." %}
|
|
</div>
|
|
|
|
{% if access_link %}
|
|
<a href="{% url 'agency_access_link_detail' access_link.slug %}"
|
|
class="btn btn-outline-info btn-sm mx-2">
|
|
<i class="fas fa-eye me-1"></i> {% trans "View Access Links Details" %}
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</div> {% endcomment %}
|
|
|
|
<!-- Applications Card -->
|
|
<div class="kaauh-card p-4">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h5 class="mb-0" style="color: var(--kaauh-teal-dark);">
|
|
<i class="fas fa-users me-2"></i>
|
|
{% trans "Submitted Applications" %} ({{ total_candidates }})
|
|
</h5>
|
|
{% if access_link %}
|
|
<a href="{% url 'agency_portal_login' %}" target="_blank" class="btn btn-outline-info btn-sm">
|
|
<i class="fas fa-external-link-alt me-1"></i> {% trans "Preview Portal" %}
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if applications %}
|
|
<div class="table-responsive">
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th class="px-4 py-3 text-uppercase small fw-bold text-muted">{% trans "Application"%}</th>
|
|
<th class="px-4 py-3 text-uppercase small fw-bold text-muted">{% trans "Contact" %}
|
|
</th>
|
|
<th class="px-4 py-3 text-uppercase small fw-bold text-muted">{% trans "Stage" %}
|
|
</th>
|
|
<th class="px-4 py-3 text-uppercase small fw-bold text-muted">{% trans "Submitted"%}</th>
|
|
<th class="px-4 py-3 text-uppercase small fw-bold text-muted text-end">{% trans "Actions" %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for application in applications %}
|
|
<tr>
|
|
<td>
|
|
<div class="fw-bold">{{ application.name }}</div>
|
|
</td>
|
|
<td>
|
|
<div class="small">
|
|
<div><i class="fas fa-envelope me-1"></i> {{ application.email }}</div>
|
|
<div><i class="fas fa-phone me-1"></i> {{ application.phone }}</div>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-info">{{ application.get_stage_display }}</span>
|
|
</td>
|
|
<td>
|
|
<div class="small text-muted">
|
|
<div class="mb-1"><i class="fas fa-envelope me-2 w-20"></i>
|
|
{{application.email }}</div>
|
|
<div><i class="fas fa-phone me-2 w-20"></i>{{ application.phone }}</div>
|
|
</div>
|
|
</td>
|
|
<td class="px-4">
|
|
<span class="badge bg-soft-info text-info rounded-pill px-3">
|
|
{{application.get_stage_display }}</span>
|
|
</td>
|
|
<td class="px-4">
|
|
<span class="small text-muted">{{ application.created_at|date:"M d, Y" }}</span>
|
|
</td>
|
|
<td class="px-4 text-end">
|
|
<a href="{% url 'application_detail' application.slug %}"
|
|
class="btn btn-sm btn-outline-primary" title="{% trans 'View Details' %}">
|
|
<i class="fas fa-eye"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="text-center py-4">
|
|
<i class="fas fa-users fa-2x text-muted mb-3"></i>
|
|
<h6 class="text-muted">{% trans "No applications submitted yet" %}</h6>
|
|
<p class="text-muted small">
|
|
{% trans "Applications will appear here once the agency submits them through their portal." %}
|
|
</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div class="col-lg-4">
|
|
<!-- Progress Card -->
|
|
<div class="kaauh-card p-4 mb-4">
|
|
<h5 class="mb-4 text-center" style="color: var(--kaauh-teal-dark);">
|
|
{% trans "Submission Progress" %}
|
|
</h5>
|
|
|
|
<div class="text-center mb-3">
|
|
<div class="progress-ring">
|
|
<svg width="120" height="120">
|
|
<circle class="progress-ring-circle"
|
|
stroke="#e9ecef"
|
|
stroke-width="8"
|
|
fill="transparent"
|
|
r="52"
|
|
cx="60"
|
|
cy="60"/>
|
|
<circle class="progress-ring-circle"
|
|
stroke="var(--kaauh-teal)"
|
|
stroke-width="8"
|
|
fill="transparent"
|
|
r="52"
|
|
cx="60"
|
|
cy="60"
|
|
style="stroke-dasharray: 326.73; stroke-dashoffset: {{ stroke_dashoffset }};"/>
|
|
</svg>
|
|
<div class="position-absolute top-50 start-50 translate-middle text-center">
|
|
<div class="h3 fw-bold mb-0 text-dark">{{ total_candidates }}</div>
|
|
<div class="small text-muted text-uppercase">{% trans "of" %} {{ assignment.max_candidates}}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="text-center">
|
|
<div class="h4 mb-1">{{ total_candidates }}</div>
|
|
<div class="text-muted">/ {{ assignment.max_candidates }} {% trans "applications" %}</div>
|
|
</div>
|
|
|
|
<div class="progress mt-3" style="height: 8px;">
|
|
{% widthratio total_candidates assignment.max_candidates 100 as progress %}
|
|
<div class="progress-bar" style="width: {{ progress }}%"></div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- Actions Card -->
|
|
<div class="kaauh-card p-4">
|
|
<h5 class="mb-4" style="color: var(--kaauh-teal-dark);">
|
|
<i class="fas fa-cog me-2"></i>
|
|
{% trans "Actions" %}
|
|
</h5>
|
|
|
|
<div class="d-grid gap-2">
|
|
<a href=""
|
|
class="btn btn-outline-primary">
|
|
<i class="fas fa-envelope me-1"></i> {% trans "Send Message" %}
|
|
</a>
|
|
|
|
{% if assignment.is_active and not assignment.is_expired %}
|
|
<button type="button" class="btn btn-outline-warning"
|
|
data-bs-toggle="modal" data-bs-target="#extendDeadlineModal">
|
|
<i class="fas fa-clock me-1"></i> {% trans "Extend Deadline" %}
|
|
</button>
|
|
{% endif %}
|
|
|
|
<a href="{% url 'agency_assignment_update' assignment.slug %}"
|
|
class="btn btn-outline-secondary">
|
|
<i class="fas fa-edit me-1"></i> {% trans "Edit Assignment" %}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Messages Section -->
|
|
{% if messages_ %}
|
|
<div class="kaauh-card p-4 mt-4">
|
|
<h5 class="mb-4" style="color: var(--kaauh-teal-dark);">
|
|
<i class="fas fa-comments me-2"></i>
|
|
{% trans "Recent Messages" %}
|
|
</h5>
|
|
|
|
<div class="row">
|
|
{% for message in messages_|slice:":6" %}
|
|
<div class="col-lg-6 mb-3">
|
|
<div class="message-item {% if not message.is_read %}unread{% endif %}">
|
|
<div class="d-flex justify-content-between align-items-start mb-2">
|
|
<div class="fw-bold">{{ message.subject }}</div>
|
|
<small class="text-muted">{{ message.created_at|date:"Y-m-d H:i" }}</small>
|
|
</div>
|
|
<div class="small text-muted mb-2">
|
|
{% trans "From" %}: {{ message.sender.get_full_name }}
|
|
</div>
|
|
<div class="small">{{ message.message|truncatewords:30 }}</div>
|
|
{% if not message.is_read %}
|
|
<span class="badge bg-info mt-2">{% trans "New" %}</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
{% if messages_.count > 6 %}
|
|
<div class="text-center mt-3">
|
|
<a href="#" class="btn btn-outline-primary btn-sm">
|
|
{% trans "View All Messages" %}
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Extend Deadline Modal -->
|
|
<div class="modal fade" id="extendDeadlineModal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">
|
|
<i class="fas fa-clock me-2"></i>
|
|
{% trans "Extend Assignment Deadline" %}
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<form method="post" action="{% url 'agency_assignment_extend_deadline' assignment.slug %}">
|
|
{% csrf_token %}
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label for="new_deadline" class="form-label">
|
|
{% trans "New Deadline" %} <span class="text-danger">*</span>
|
|
</label>
|
|
<input type="datetime-local" class="form-control" id="new_deadline"
|
|
name="new_deadline" required>
|
|
<small class="form-text text-muted">
|
|
{% trans "Current deadline:" %} {{ assignment.deadline_date|date:"Y-m-d H:i" }}
|
|
</small>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
|
{% trans "Cancel" %}
|
|
</button>
|
|
<button type="submit" class="btn btn-main-action">
|
|
<i class="fas fa-clock me-1"></i> {% trans "Extend Deadline" %}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block customJS %}
|
|
<script>
|
|
function copyToClipboard(text) {
|
|
navigator.clipboard.writeText(text).then(function() {
|
|
// Show success message
|
|
const toast = document.createElement('div');
|
|
toast.className = 'position-fixed top-0 end-0 p-3';
|
|
toast.style.zIndex = '1050';
|
|
toast.innerHTML = `
|
|
<div class="toast show" role="alert">
|
|
<div class="toast-header">
|
|
<strong class="me-auto">{% trans "Success" %}</strong>
|
|
<button type="button" class="btn-close" data-bs-dismiss="toast"></button>
|
|
</div>
|
|
<div class="toast-body">
|
|
{% trans "Token copied to clipboard!" %}
|
|
</div>
|
|
</div>
|
|
`;
|
|
document.body.appendChild(toast);
|
|
|
|
setTimeout(() => {
|
|
toast.remove();
|
|
}, 3000);
|
|
});
|
|
}
|
|
|
|
function copyToClipboard(elementId) {
|
|
const element = document.getElementById(elementId);
|
|
element.select();
|
|
document.execCommand('copy');
|
|
|
|
// Show feedback
|
|
const button = element.nextElementSibling;
|
|
const originalHTML = button.innerHTML;
|
|
button.innerHTML = '<i class="fas fa-check"></i>';
|
|
button.classList.add('btn-success');
|
|
button.classList.remove('btn-outline-secondary');
|
|
|
|
setTimeout(() => {
|
|
button.innerHTML = originalHTML;
|
|
button.classList.remove('btn-success');
|
|
button.classList.add('btn-outline-secondary');
|
|
}, 2000);
|
|
}
|
|
|
|
function confirmDeactivate() {
|
|
if (confirm('{% trans "Are you sure you want to deactivate this access link? Agencies will no longer be able to use it." %}')) {
|
|
// Submit form to deactivate
|
|
window.location.href = '';
|
|
}
|
|
}
|
|
|
|
function confirmReactivate() {
|
|
if (confirm('{% trans "Are you sure you want to reactivate this access link?" %}')) {
|
|
// Submit form to reactivate
|
|
window.location.href = '';
|
|
}
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Set minimum datetime for new deadline
|
|
const deadlineInput = document.getElementById('new_deadline');
|
|
if (deadlineInput) {
|
|
const currentDeadline = new Date('{{ assignment.deadline_date|date:"Y-m-d\\TH:i" }}');
|
|
const now = new Date();
|
|
const minDateTime = new Date(Math.max(currentDeadline, now));
|
|
|
|
const localDateTime = new Date(minDateTime.getTime() - minDateTime.getTimezoneOffset() * 60000)
|
|
.toISOString()
|
|
.slice(0, 16);
|
|
deadlineInput.min = localDateTime;
|
|
deadlineInput.value = localDateTime;
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %}
|