434 lines
18 KiB
HTML
434 lines
18 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}Assign Staff to {{ job.title }}{% endblock %}
|
|
|
|
{% block customCSS %}
|
|
<style>
|
|
/* Theme Variables and Global Styles */
|
|
:root {
|
|
--kaauh-teal: #00636e;
|
|
--kaauh-teal-dark: #004a53;
|
|
--kaauh-border: #eaeff3;
|
|
--kaauh-primary-text: #343a40;
|
|
}
|
|
|
|
/* Primary Color Overrides */
|
|
.text-primary { color: var(--kaauh-teal) !important; }
|
|
.bg-primary { background-color: var(--kaauh-teal) !important; }
|
|
.btn-main-action {
|
|
background-color: var(--kaauh-teal) !important;
|
|
border-color: var(--kaauh-teal) !important;
|
|
color: white !important;
|
|
font-weight: 600;
|
|
padding: 0.6rem 1.2rem;
|
|
transition: all 0.2s ease;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
}
|
|
.btn-main-action:hover {
|
|
background-color: var(--kaauh-teal-dark) !important;
|
|
border-color: var(--kaauh-teal-dark) !important;
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
|
}
|
|
.btn-outline-secondary {
|
|
color: var(--kaauh-teal-dark) !important;
|
|
border-color: var(--kaauh-teal) !important;
|
|
}
|
|
.btn-outline-secondary:hover {
|
|
background-color: var(--kaauh-teal-dark) !important;
|
|
color: white !important;
|
|
border-color: var(--kaauh-teal-dark) !important;
|
|
}
|
|
|
|
/* Header styling */
|
|
.job-header-card {
|
|
background: linear-gradient(135deg, var(--kaauh-teal), var(--kaauh-teal-dark));
|
|
color: white;
|
|
border-radius: 0.75rem 0.75rem 0 0;
|
|
padding: 1.5rem;
|
|
box-shadow: 0 4px 10px rgba(0,0,0,0.15);
|
|
}
|
|
.job-header-card h1 {
|
|
font-weight: 700;
|
|
margin: 0;
|
|
font-size: 1.8rem;
|
|
}
|
|
|
|
/* Card enhancements */
|
|
.kaauh-card, .card {
|
|
border: 1px solid var(--kaauh-border);
|
|
border-radius: 0.75rem;
|
|
overflow: hidden;
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
|
|
background-color: white;
|
|
}
|
|
.kaauh-card:not(.no-hover):hover,
|
|
.card:not(.no-hover):hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 6px 16px rgba(0,0,0,0.1);
|
|
}
|
|
|
|
/* Standard Card Header */
|
|
.card-header {
|
|
font-weight: 600;
|
|
padding: 1rem 1.25rem;
|
|
background-color: #f8f9fa;
|
|
border-bottom: 1px solid var(--kaauh-border);
|
|
}
|
|
|
|
/* Form styling */
|
|
.form-control, .form-select {
|
|
border-radius: 0.5rem;
|
|
border: 1px solid #ced4da;
|
|
padding: 0.5rem 0.75rem;
|
|
font-size: 0.9rem;
|
|
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
|
}
|
|
.form-control:focus, .form-select:focus {
|
|
border-color: var(--kaauh-teal);
|
|
box-shadow: 0 0 0 0.2rem rgba(0, 99, 110, 0.25);
|
|
}
|
|
|
|
/* Staff member cards */
|
|
.staff-card {
|
|
border: 1px solid var(--kaauh-border);
|
|
border-radius: 0.75rem;
|
|
transition: all 0.2s ease;
|
|
height: 100%;
|
|
}
|
|
.staff-card:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 6px 16px rgba(0,0,0,0.1);
|
|
border-color: var(--kaauh-teal);
|
|
}
|
|
|
|
/* Badge styling */
|
|
.badge {
|
|
font-size: 0.8rem;
|
|
padding: 0.4em 0.8em;
|
|
border-radius: 0.4rem;
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* Table styling */
|
|
.table {
|
|
margin-bottom: 0;
|
|
}
|
|
.table th {
|
|
background-color: var(--kaauh-border);
|
|
font-weight: 600;
|
|
color: var(--kaauh-teal-dark);
|
|
border-bottom: 2px solid var(--kaauh-teal);
|
|
}
|
|
.table tbody tr:hover {
|
|
background-color: #f1f3f4;
|
|
}
|
|
|
|
/* Page header styling */
|
|
.page-header {
|
|
color: var(--kaauh-teal-dark);
|
|
font-weight: 700;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid py-4">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<!-- Page Header -->
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<div>
|
|
<h1 class="page-header h3 mb-1">Assign Staff to Job</h1>
|
|
<p class="text-secondary mb-0">Job: {{ job.title }} ({{ job.internal_job_id }})</p>
|
|
</div>
|
|
<a href="{% url 'job_detail' job.slug %}" class="btn btn-outline-secondary">
|
|
<i class="fas fa-arrow-left me-2"></i>Back to Job Details
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Job Information Card -->
|
|
<div class="kaauh-card mb-4">
|
|
<div class="job-header-card">
|
|
<h5 class="mb-0"><i class="fas fa-briefcase me-2"></i>Job Information</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row mx-2 my-2">
|
|
<div class="col-md-6">
|
|
<p><strong>Department:</strong> {{ job.get_department_display|default:job.department }}</p>
|
|
<p><strong>Job Type:</strong> {{ job.get_job_type_display }}</p>
|
|
<p><strong>Workplace Type:</strong> {{ job.get_workplace_type_display }}</p>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<p><strong>Status:</strong>
|
|
<span class="badge {% if job.status == 'ACTIVE' %}bg-success{% elif job.status == 'CLOSED' %}bg-danger{% else %}bg-secondary{% endif %}">
|
|
{{ job.get_status_display }}
|
|
</span>
|
|
</p>
|
|
<p><strong>Applications:</strong> {{ applications.count }}</p>
|
|
<p><strong>Created:</strong> {{ job.created_at|date:"M d, Y" }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Staff Assignment Form -->
|
|
<div class="kaauh-card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0 text-primary"><i class="fas fa-user-tie me-2"></i>Staff Assignment</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if messages %}
|
|
{% for message in messages %}
|
|
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
|
|
{{ message }}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
|
|
<form method="post" id="staffAssignmentForm" class="mx-2 my-2" action=".">
|
|
{% csrf_token %}
|
|
{{form.as_p}}
|
|
|
|
{% comment %} <div class="row mb-3 ">
|
|
<div class="col-md-12">
|
|
<label for="{{ form.staff.id_for_label }}" class="form-label fw-bold">
|
|
{{ form.staff.label }} <span class="text-danger">*</span>
|
|
</label>
|
|
{{ form.staff }}
|
|
{% if form.staff.errors %}
|
|
<div class="text-danger small mt-1">
|
|
{% for error in form.staff.errors %}
|
|
{{ error }}
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
<div class="form-text">Select a staff member to assign to this job posting.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-12">
|
|
<label for="{{ form.assignment_date.id_for_label }}" class="form-label fw-bold">
|
|
{{ form.assignment_date.label }}
|
|
</label>
|
|
{{ form.assignment_date }}
|
|
{% if form.assignment_date.errors %}
|
|
<div class="text-danger small mt-1">
|
|
{% for error in form.assignment_date.errors %}
|
|
{{ error }}
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
<div class="form-text">Date when staff assignment becomes effective.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-12">
|
|
<label for="{{ form.notes.id_for_label }}" class="form-label fw-bold">
|
|
{{ form.notes.label }}
|
|
</label>
|
|
{{ form.notes }}
|
|
{% if form.notes.errors %}
|
|
<div class="text-danger small mt-1">
|
|
{% for error in form.notes.errors %}
|
|
{{ error }}
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
<div class="form-text">Optional notes about this staff assignment.</div>
|
|
</div>
|
|
</div> {% endcomment %}
|
|
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<button type="submit" class="btn btn-main-action">
|
|
<i class="fas fa-user-plus me-2"></i>Assign Staff to Job
|
|
</button>
|
|
<a href="{% url 'job_detail' job.slug %}" class="btn btn-outline-secondary ms-2">
|
|
<i class="fas fa-times me-2"></i>Cancel
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Current Staff Assignments -->
|
|
{% if job.staff_assignments.exists %}
|
|
<div class="kaauh-card mt-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0 text-primary"><i class="fas fa-users me-2"></i>Current Staff Assignments</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="table-responsive">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>Staff Member</th>
|
|
<th>Email</th>
|
|
<th>Assignment Date</th>
|
|
<th>Notes</th>
|
|
<th>Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for assignment in job.staff_assignments.all %}
|
|
<tr>
|
|
<td>
|
|
<strong>{{ assignment.staff.get_full_name|default:assignment.staff.username }}</strong>
|
|
{% if assignment.staff.is_active %}
|
|
<span class="badge bg-success ms-2">Active</span>
|
|
{% else %}
|
|
<span class="badge bg-danger ms-2">Inactive</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>{{ assignment.staff.email }}</td>
|
|
<td>{{ assignment.assignment_date|date:"M d, Y" }}</td>
|
|
<td>{{ assignment.notes|default:"-" }}</td>
|
|
<td>
|
|
<span class="badge bg-primary">Assigned</span>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Available Staff Members -->
|
|
<div class="kaauh-card mt-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0 text-primary"><i class="fas fa-users me-2"></i>Available Staff Members</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
{% for staff_user in staff_users %}
|
|
<div class="col-md-6 col-lg-4 mb-3">
|
|
<div class="staff-card card h-100">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center mb-2">
|
|
<div class="rounded-circle text-white d-flex align-items-center justify-content-center me-3" style="width: 40px; height: 40px; background-color: var(--kaauh-teal);">
|
|
{% if staff_user.first_name %}
|
|
{{ staff_user.first_name.0 }}{{ staff_user.last_name.0 }}
|
|
{% else %}
|
|
{{ staff_user.username.0|upper }}
|
|
{% endif %}
|
|
</div>
|
|
<div>
|
|
<h6 class="mb-0">{{ staff_user.get_full_name|default:staff_user.username }}</h6>
|
|
<small class="text-muted">{{ staff_user.email }}</small>
|
|
</div>
|
|
</div>
|
|
<div class="mt-2">
|
|
{% if staff_user.is_active %}
|
|
<span class="badge bg-success">Active</span>
|
|
{% else %}
|
|
<span class="badge bg-danger">Inactive</span>
|
|
{% endif %}
|
|
<span class="badge bg-primary ms-1">Staff</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% empty %}
|
|
<div class="col-12">
|
|
<div class="alert alert-warning">
|
|
<i class="fas fa-exclamation-triangle me-2"></i>
|
|
No staff members available. Please create staff accounts first.
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal for Staff Assignment Confirmation -->
|
|
<div class="modal fade" id="staffAssignmentModal" tabindex="-1" aria-labelledby="staffAssignmentModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="staffAssignmentModalLabel">
|
|
<i class="fas fa-user-plus me-2"></i>Confirm Staff Assignment
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Are you sure you want to assign this staff member to the job <strong>{{ job.title }}</strong>?</p>
|
|
<div id="selectedStaffInfo"></div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="button" class="btn btn-main-action" id="confirmAssignmentBtn">
|
|
<i class="fas fa-check me-2"></i>Confirm Assignment
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const form = document.getElementById('staffAssignmentForm');
|
|
const modal = new bootstrap.Modal(document.getElementById('staffAssignmentModal'));
|
|
const confirmBtn = document.getElementById('confirmAssignmentBtn');
|
|
const selectedStaffInfo = document.getElementById('selectedStaffInfo');
|
|
|
|
// Handle form submission with modal confirmation
|
|
if (form) {
|
|
form.addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
|
|
const staffSelect = document.getElementById('{{ form.staff.id_for_label }}');
|
|
const selectedOption = staffSelect.options[staffSelect.selectedIndex];
|
|
|
|
if (selectedOption.value) {
|
|
// Show selected staff info in modal
|
|
selectedStaffInfo.innerHTML = `
|
|
<div class="alert alert-info">
|
|
<strong>Selected Staff Member:</strong><br>
|
|
Name: ${selectedOption.text}<br>
|
|
This assignment will take effect immediately.
|
|
</div>
|
|
`;
|
|
|
|
// Show modal
|
|
modal.show();
|
|
} else {
|
|
alert('Please select a staff member.');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Handle modal confirmation
|
|
if (confirmBtn) {
|
|
confirmBtn.addEventListener('click', function() {
|
|
// Hide modal
|
|
modal.hide();
|
|
|
|
// Submit the form
|
|
form.submit();
|
|
});
|
|
}
|
|
|
|
// Auto-focus on staff select field
|
|
const staffSelect = document.getElementById('{{ form.staff.id_for_label }}');
|
|
if (staffSelect) {
|
|
staffSelect.focus();
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %}
|