599 lines
16 KiB
HTML
599 lines
16 KiB
HTML
{% 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 %}
|