added job_not_expired decorator

This commit is contained in:
Faheed 2025-10-07 17:54:46 +03:00
parent 285d2aea18
commit cbf4630071
10 changed files with 207 additions and 91 deletions

17
recruitment/decorators.py Normal file
View File

@ -0,0 +1,17 @@
from functools import wraps
from datetime import date
from django.shortcuts import redirect, get_object_or_404
from django.http import HttpResponseNotFound
def job_not_expired(view_func):
@wraps(view_func)
def _wrapped_view(request, job_id, *args, **kwargs):
from .models import JobPosting
job = get_object_or_404(JobPosting, pk=job_id)
if job.expiration_date and job.application_deadline< date.today():
return redirect('expired_job_page')
return view_func(request, job_id, *args, **kwargs)
return _wrapped_view

View File

@ -1,129 +1,228 @@
{% extends "base.html" %}
{% block title %}{{ job.title }} - University ATS{% endblock %}
{% block customCSS %}
<style>
/* ---------------------------------------------------------------------- */
/* THEME STYLES (Keep from previous response) */
/* ---------------------------------------------------------------------- */
:root {
--kaauh-teal: #00636e;
--kaauh-teal-dark: #004a53;
--success: #198754;
/* Define a subtle background for mobile sticky bar */
--light-bg: #f8f9fa;
}
.btn-main-action {
background-color: var(--kaauh-teal);
color: white;
border: none;
transition: background-color 0.3s ease, transform 0.2s ease;
box-shadow: 0 4px 12px rgba(0, 99, 110, 0.3);
}
.btn-main-action:hover {
background-color: var(--kaauh-teal-dark);
color: white;
transform: translateY(-1px);
}
.bg-kaauh-teal-dark {
background-color: var(--kaauh-teal-dark) !important;
}
/* ---------------------------------------------------------------------- */
/* MOBILE RESPONSIVE STYLES */
/* ---------------------------------------------------------------------- */
/* 1. Mobile Fixed Footer Bar for Application */
@media (max-width: 991.98px) {
/* Fix the "Apply" button bar to the bottom on mobile/tablet */
.mobile-fixed-apply-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
width: 100%;
padding: 15px;
background-color: var(--light-bg); /* Use a light background */
border-top: 1px solid #ddd;
z-index: 1000; /* Ensure it stays above everything */
box-shadow: 0 -4px 10px rgba(0, 0, 0, 0.08);
}
/* Add padding to the bottom of the body content to prevent it from hiding under the fixed bar */
body {
padding-bottom: 90px;
}
/* Adjust header font size for small screens */
.card-header h2 {
font-size: 1.25rem !important;
}
/* Change job overview grid to single column on small phones */
.row-cols-md-2 {
--bs-gutter-x: 1.5rem;
--bs-gutter-y: 1rem;
}
.row-cols-md-2 > .col {
flex: 0 0 100%; /* force to 1 column */
max-width: 100%;
}
}
</style>
{% endblock %}
{% block content %}
<div class="row mb-5">
<div class="col-lg-8">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h2>{{ job.title }}</h2>
<span class="badge bg-{{ job.status|lower }} status-badge">
<div class="col-lg-4 order-lg-2 order-1 d-none d-lg-block">
<div class="card shadow-sm sticky-top" style="top: 90px;">
<div class="card-header bg-kaauh-teal-dark text-white">
<h5 class="mb-0"><i class="fas fa-file-signature me-2"></i>Ready to Apply?</h5>
</div>
<div class="card-body text-center">
<p class="text-muted">Review the job details, then apply below.</p>
<a href="#" class="btn btn-main-action btn-lg w-100">
<i class="fas fa-paper-plane me-2"></i> Apply for this Position
</a>
{% comment %} <p class="text-muted mt-3 mb-0">
<small>Application ID: **{{ job.pk }}**</small>
</p> {% endcomment %}
</div>
</div>
</div>
<div class="col-lg-8 order-lg-1 order-2">
<div class="card shadow-sm">
<div class="card-header bg-kaauh-teal-dark text-white d-flex justify-content-between align-items-center">
<h2 class="h3 mb-0 fw-bold">{{ job.title }}</h2>
{% with status_class=job.status|lower %}
<span class="badge
{% if status_class == 'open' %}bg-success
{% elif status_class == 'closed' %}bg-danger
{% elif status_class == 'draft' %}bg-secondary
{% else %}bg-primary
{% endif %}
status-badge fw-bold p-2">
{{ job.get_status_display }}
</span>
{% endwith %}
</div>
<div class="card-body">
<!-- Job Details -->
<div class="row mb-3">
<div class="col-md-6">
<strong>Department:</strong> {{ job.department|default:"Not specified" }}
</div>
<div class="col-md-6">
<strong>Position Number:</strong> {{ job.position_number|default:"Not specified" }}
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<strong>Job Type:</strong> {{ job.get_job_type_display }}
<h4 class="mb-3" style="color: var(--kaauh-teal-dark);">Job Overview</h4>
<div class="row row-cols-1 row-cols-md-2 g-3 mb-4">
{% if job.salary_range %}
<div class="col">
<i class="fas fa-money-bill-wave text-success me-2"></i>
<strong>Salary:</strong>
<span class="fw-bold text-success">{{ job.salary_range }}</span>
</div>
<div class="col-md-6">
<strong>Workplace:</strong> {{ job.get_workplace_type_display }}
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<strong>Location:</strong> {{ job.get_location_display }}
</div>
<div class="col-md-6">
<strong>Created By:</strong> {{ job.created_by|default:"Not specified" }}
</div>
</div>
{% if job.salary_range %}
<div class="row mb-3">
<div class="col-12">
<strong>Salary Range:</strong> {{ job.salary_range }}
</div>
</div>
{% endif %}
{% if job.start_date %}
<div class="row mb-3">
<div class="col-12">
<strong>Start Date:</strong> {{ job.start_date }}
</div>
</div>
{% endif %}
{% if job.application_deadline %}
<div class="row mb-3">
<div class="col-12">
<strong>Application Deadline:</strong> {{ job.application_deadline }}
{% if job.is_expired %}
<span class="badge bg-danger">EXPIRED</span>
{% endif %}
<div class="col">
<i class="fas fa-calendar-alt text-muted me-2"></i>
<strong>Deadline:</strong>
{% if job.application_deadline %}
{{ job.application_deadline|date:"M d, Y" }}
{% if job.is_expired %}
<span class="badge bg-danger ms-2">EXPIRED</span>
{% endif %}
{% else %}
<span class="text-muted">Not specified</span>
{% endif %}
</div>
<div class="col">
<i class="fas fa-briefcase text-muted me-2"></i>
<strong>Job Type:</strong> {{ job.get_job_type_display }}
</div>
<div class="col">
<i class="fas fa-map-marker-alt text-muted me-2"></i>
<strong>Location:</strong> {{ job.get_location_display }}
</div>
<div class="col">
<i class="fas fa-building text-muted me-2"></i>
<strong>Department:</strong> {{ job.department|default:"Not specified" }}
</div>
<div class="col">
<i class="fas fa-hashtag text-muted me-2"></i>
<strong>JOB ID:</strong> {{ job.internal_job_id|default:"N/A" }}
</div>
<div class="col">
<i class="fas fa-desktop text-muted me-2"></i>
<strong>Workplace:</strong> {{ job.get_workplace_type_display }}
</div>
<div class="col">
<i class="fas fa-user-tie text-muted me-2"></i>
<strong>Created By:</strong> {{ job.created_by|default:"N/A" }}
</div>
</div>
{% endif %}
<!-- Description -->
{% if job.description %}
<div class="mb-3">
<h5>Description</h5>
<div>{{ job.description|linebreaks }}</div>
<hr class="my-4">
<div class="mb-4">
<h5 class="fw-bold" style="color: var(--kaauh-teal-dark);">
<i class="fas fa-info-circle me-2"></i>Job Description
</h5>
<div class="text-secondary">{{ job.description|linebreaks }}</div>
</div>
{% endif %}
{% if job.qualifications %}
<div class="mb-3">
<h5>Qualifications</h5>
<div>{{ job.qualifications|linebreaks }}</div>
<hr class="my-4">
<div class="mb-4">
<h5 class="fw-bold" style="color: var(--kaauh-teal-dark);">
<i class="fas fa-graduation-cap me-2"></i>Qualifications
</h5>
<div class="text-secondary">{{ job.qualifications|linebreaks }}</div>
</div>
{% endif %}
{% if job.benefits %}
<div class="mb-3">
<h5>Benefits</h5>
<div>{{ job.benefits|linebreaks }}</div>
<hr class="my-4">
<div class="mb-4">
<h5 class="fw-bold" style="color: var(--kaauh-teal-dark);">
<i class="fas fa-hand-holding-usd me-2"></i>Benefits
</h5>
<div class="text-secondary">{{ job.benefits|linebreaks }}</div>
</div>
{% endif %}
{% if job.application_instructions %}
<div class="mb-3">
<h5>Application Instructions</h5>
<div>{{ job.application_instructions|linebreaks }}</div>
<hr class="my-4">
<div class="mb-4">
<h5 class="fw-bold" style="color: var(--kaauh-teal-dark);">
<i class="fas fa-file-alt me-2"></i>Application Instructions
</h5>
<div class="text-secondary">{{ job.application_instructions|linebreaks }}</div>
</div>
{% endif %}
</div>
</div>
</div>
<div class="col-lg-4">
<!-- Add this section below your existing job details -->
<div class="card mt-4">
<div class="card-header bg-success text-white">
<h5><i class="fas fa-file-signature"></i> Ready to Apply?</h5>
</div>
<div class="card-body">
<p>Review the job details on the left, then click the button below to submit your application.</p>
<a href="{% url 'form_wizard' job.candidate.pk %}" class="btn btn-success btn-lg w-100">
<i class="fas fa-paper-plane"></i> Apply for this Position
</a>
<p class="text-muted mt-2">
<small>You'll be redirected to our secure application form where you can upload your resume and provide additional details.</small>
</p>
</div>
</div>
</div>
</div>
<div class="mobile-fixed-apply-bar d-lg-none">
{% if job.form_template.pk %}
<a href="{% url 'form_wizard' job.form_template.pk %}" class="btn btn-main-action btn-lg w-100">
<i class="fas fa-paper-plane me-2"></i> Apply for this Position
</a>
{% endif %}
</div>
{% endblock %}