kaauh_ats/templates/jobs/job_bank.html
2025-12-10 13:56:51 +03:00

599 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% load static %}
{% block title %}Job Bank - All Opportunities{% endblock %}
{% block customCSS %}
<style>
.job-bank-container {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
}
.job-bank-header {
background: linear-gradient(135deg, #00636e 0%, #004a53 100%);
color: white;
padding: 2rem;
border-radius: 15px;
margin-bottom: 2rem;
text-align: center;
}
.job-bank-header h1 {
margin: 0 0 0.5rem 0;
font-size: 2.5rem;
font-weight: 700;
}
.job-bank-header p {
margin: 0;
font-size: 1.1rem;
opacity: 0.9;
}
.filters-section {
background: white;
border-radius: 12px;
padding: 1.5rem;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
margin-bottom: 2rem;
}
.filters-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
margin-bottom: 1rem;
}
.filter-group {
display: flex;
flex-direction: column;
}
.filter-group label {
font-weight: 600;
margin-bottom: 0.5rem;
color: #333;
}
.filter-group select,
.filter-group input {
padding: 0.75rem;
border: 2px solid #e1e5e9;
border-radius: 8px;
font-size: 0.95rem;
transition: all 0.3s ease;
}
.filter-group select:focus,
.filter-group input:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.search-box {
position: relative;
}
.search-box input {
width: 100%;
padding-left: 3rem;
}
.search-box::before {
content: "🔍";
position: absolute;
left: 1rem;
top: 50%;
transform: translateY(-50%);
font-size: 1.2rem;
}
.filters-actions {
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
.btn-filter {
padding: 0.75rem 1.5rem;
border: none;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.btn-primary {
background: #00636e;
color: white;
}
.btn-primary:hover {
background: #004a53;
transform: translateY(-2px);
}
.btn-secondary {
background: #6c757d;
color: white;
}
.btn-secondary:hover {
background: #5a6268;
}
.results-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1.5rem;
padding: 1rem;
background: white;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
}
.results-count {
font-size: 1.1rem;
font-weight: 600;
color: #333;
}
.sort-dropdown {
padding: 0.5rem 1rem;
border: 2px solid #e1e5e9;
border-radius: 6px;
background: white;
}
.jobs-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 1.5rem;
margin-bottom: 2rem;
}
.job-card {
background: white;
border-radius: 12px;
padding: 1.5rem;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
transition: all 0.3s ease;
border: 2px solid transparent;
position: relative;
overflow: hidden;
}
.job-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, #00636e, #004a53);
}
.job-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 25px rgba(0,0,0,0.15);
border-color: #004a53;
}
.job-status {
position: absolute;
top: 1rem;
right: 1rem;
padding: 0.25rem 0.75rem;
border-radius: 20px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
}
.status-active {
background: #28a745;
color: white;
}
.status-inactive {
background: #dc3545;
color: white;
}
.status-draft {
background: #ffc107;
color: #212529;
}
.job-title {
font-size: 1.3rem;
font-weight: 700;
color: #333;
margin-bottom: 0.5rem;
line-height: 1.3;
}
.job-department {
color: #667eea;
font-weight: 600;
margin-bottom: 0.5rem;
}
.job-meta {
display: flex;
flex-wrap: wrap;
gap: 1rem;
margin-bottom: 1rem;
}
.meta-item {
display: flex;
align-items: center;
gap: 0.3rem;
font-size: 0.9rem;
color: #666;
}
.meta-icon {
font-size: 1rem;
}
.job-description {
color: #666;
line-height: 1.6;
margin-bottom: 1rem;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.job-actions {
display: flex;
gap: 0.75rem;
flex-wrap: wrap;
}
.btn-apply {
background: linear-gradient(135deg, #004a53, #00636e);
color: white;
padding: 0.75rem 1.5rem;
border: none;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.btn-apply:hover {
transform: translateY(-2px);
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
}
.btn-view {
background: transparent;
color: #00636e;
padding: 0.75rem 1.5rem;
border: 2px solid #004a53;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
.btn-view:hover {
background: #004a53;
color: white;
}
.pagination {
display: flex;
justify-content: center;
align-items: center;
gap: 0.5rem;
margin-top: 2rem;
}
.pagination a,
.pagination span {
padding: 0.75rem 1rem;
border: 2px solid #e1e5e9;
border-radius: 8px;
text-decoration: none;
color: #333;
font-weight: 500;
transition: all 0.3s ease;
}
.pagination a:hover {
background: #667eea;
color: white;
border-color: #667eea;
}
.pagination .current {
background: #667eea;
color: white;
border-color: #667eea;
}
.no-results {
text-align: center;
padding: 3rem;
background: white;
border-radius: 12px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.no-results h3 {
color: #333;
margin-bottom: 1rem;
}
.no-results p {
color: #666;
margin-bottom: 1.5rem;
}
@media (max-width: 768px) {
.job-bank-container {
padding: 1rem;
}
.filters-grid {
grid-template-columns: 1fr;
}
.jobs-grid {
grid-template-columns: 1fr;
}
.results-header {
flex-direction: column;
gap: 1rem;
align-items: stretch;
}
.filters-actions {
flex-direction: column;
}
.btn-filter {
width: 100%;
justify-content: center;
}
}
</style>
{% endblock %}
{% block content %}
<div class="job-bank-container">
<!-- Header Section -->
<div class="job-bank-header">
<h1>🏦 Job Bank</h1>
<p>Explore all available opportunities across departments and find your perfect role</p>
</div>
<!-- Filters Section -->
<div class="filters-section">
<form method="GET" class="filters-form">
<div class="filters-grid">
<!-- Search Box -->
<div class="filter-group search-box">
<label for="search">🔍 Search Jobs</label>
<input
type="text"
id="search"
name="q"
value="{{ search_query }}"
placeholder="Search by title, department, or keywords..."
>
</div>
<!-- Department Filter -->
<div class="filter-group">
<label for="department">📁 Department</label>
<select id="department" name="department">
<option value="">All Departments</option>
{% for dept in departments %}
<option value="{{ dept }}" {% if department_filter == dept %}selected{% endif %}>
{{ dept }}
</option>
{% endfor %}
</select>
</div>
<!-- Job Type Filter -->
<div class="filter-group">
<label for="job_type">💼 Job Type</label>
<select id="job_type" name="job_type">
<option value="">All Types</option>
{% for key, value in job_types.items %}
<option value="{{ key }}" {% if job_type_filter == key %}selected{% endif %}>
{{ value }}
</option>
{% endfor %}
</select>
</div>
<!-- Workplace Type Filter -->
<div class="filter-group">
<label for="workplace_type">🏢 Workplace Type</label>
<select id="workplace_type" name="workplace_type">
<option value="">All Types</option>
{% for key, value in workplace_types.items %}
<option value="{{ key }}" {% if workplace_type_filter == key %}selected{% endif %}>
{{ value }}
</option>
{% endfor %}
</select>
</div>
<!-- Status Filter -->
<div class="filter-group">
<label for="status">📊 Status</label>
<select id="status" name="status">
<option value="">All Statuses</option>
{% for key, value in status_choices.items %}
<option value="{{ key }}" {% if status_filter == key %}selected{% endif %}>
{{ value }}
</option>
{% endfor %}
</select>
</div>
<!-- Date Filter -->
<div class="filter-group">
<label for="date_filter">📅 Posted Within</label>
<select id="date_filter" name="date_filter">
<option value="">Any Time</option>
<option value="week" {% if date_filter == 'week' %}selected{% endif %}>Last Week</option>
<option value="month" {% if date_filter == 'month' %}selected{% endif %}>Last Month</option>
<option value="quarter" {% if date_filter == 'quarter' %}selected{% endif %}>Last 3 Months</option>
</select>
</div>
<!-- Sort By -->
<div class="filter-group">
<label for="sort">🔄 Sort By</label>
<select id="sort" name="sort">
<option value="-created_at" {% if sort_by == '-created_at' %}selected{% endif %}>Newest First</option>
<option value="created_at" {% if sort_by == 'created_at' %}selected{% endif %}>Oldest First</option>
<option value="title" {% if sort_by == 'title' %}selected{% endif %}>Title (A-Z)</option>
<option value="-title" {% if sort_by == '-title' %}selected{% endif %}>Title (Z-A)</option>
<option value="department" {% if sort_by == 'department' %}selected{% endif %}>Department (A-Z)</option>
<option value="-department" {% if sort_by == '-department' %}selected{% endif %}>Department (Z-A)</option>
</select>
</div>
</div>
<!-- Filter Actions -->
<div class="filters-actions">
<button type="submit" class="btn-filter btn-primary">
🔍 Apply Filters
</button>
<a href="{% url 'job_bank' %}" class="btn-filter btn-secondary">
🔄 Clear All
</a>
</div>
</form>
</div>
<!-- Results Header -->
<div class="results-header">
<div class="results-count">
📊 Found <strong>{{ total_jobs }}</strong> job{{ total_jobs|pluralize }}
{% if search_query or department_filter or job_type_filter or workplace_type_filter or status_filter or date_filter %}
with filters applied
{% endif %}
</div>
</div>
<!-- Jobs Grid -->
{% if page_obj.object_list %}
<div class="jobs-grid">
{% for job in page_obj.object_list %}
<div class="job-card">
<!-- Status Badge -->
<div class="job-status status-{{ job.status|lower }}">
{{ job.get_status_display }}
</div>
<!-- Job Title -->
<h3 class="job-title">{{ job.title }}</h3>
<!-- Department -->
<div class="job-department">📁 {{ job.department|default:"General" }}</div>
<!-- Job Meta -->
<div class="job-meta">
<div class="meta-item">
<span class="meta-icon">💼</span>
<span>{{ job.get_job_type_display }}</span>
</div>
<div class="meta-item">
<span class="meta-icon">🏢</span>
<span>{{ job.get_workplace_type_display }}</span>
</div>
{% if job.max_applications %}
<div class="meta-item">
<span class="meta-icon">👥</span>
<span>{{ job.max_applications }} positions</span>
</div>
{% endif %}
</div>
<!-- Description Preview -->
<div class="job-description">
{{ job.description|striptags|truncatewords:30 }}
</div>
<!-- Actions -->
<div class="job-actions">
{% if job.status == 'ACTIVE' %}
<a href="{% url 'job_applicants' job.slug %}" class="btn-apply">
<20> View Applicants
</a>
{% endif %}
<a href="{% url 'job_detail' job.slug %}" class="btn-view">
👁️ View Details
</a>
</div>
</div>
{% endfor %}
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
<div class="pagination">
{% if page_obj.has_previous %}
<a href="?page=1{% if request.GET.urlencode %}&{{ request.GET.urlencode }}{% endif %}">« First</a>
<a href="?page={{ page_obj.previous_page_number }}{% if request.GET.urlencode %}&{{ request.GET.urlencode }}{% endif %}"> Previous</a>
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}{% if request.GET.urlencode %}&{{ request.GET.urlencode }}{% endif %}">Next </a>
<a href="?page={{ page_obj.paginator.num_pages }}{% if request.GET.urlencode %}&{{ request.GET.urlencode }}{% endif %}">Last »</a>
{% endif %}
</div>
{% endif %}
{% else %}
<!-- No Results -->
<div class="no-results">
<h3>😔 No Jobs Found</h3>
<p>
{% if search_query or department_filter or job_type_filter or workplace_type_filter or status_filter or date_filter %}
We couldn't find any jobs matching your current filters. Try adjusting your search criteria or clearing some filters.
{% else %}
There are currently no job postings in the system. Check back later for new opportunities!
{% endif %}
</p>
<a href="{% url 'job_bank' %}" class="btn-filter btn-primary">
🔄 Clear Filters
</a>
</div>
{% endif %}
</div>
{% endblock %}