Merge pull request 'frontend' (#5) from frontend into main
Reviewed-on: #5
This commit is contained in:
commit
921fe781d7
Binary file not shown.
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
17
recruitment/decorators.py
Normal file
17
recruitment/decorators.py
Normal 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
|
||||
Binary file not shown.
@ -12,6 +12,7 @@ urlpatterns = [
|
||||
path('jobs/<slug:slug>/update/', views.edit_job, name='job_update'),
|
||||
# path('jobs/<slug:slug>/delete/', views., name='job_delete'),
|
||||
path('jobs/<slug:slug>/', views.job_detail, name='job_detail'),
|
||||
path('jobs/<slug:slug>/candidate/', views.job_detail_candidate, name='job_detail_candidate'),
|
||||
|
||||
# LinkedIn Integration URLs
|
||||
path('jobs/<slug:slug>/post-to-linkedin/', views.post_to_linkedin, name='post_to_linkedin'),
|
||||
|
||||
@ -242,7 +242,12 @@ def job_detail(request, slug):
|
||||
'offer_count': offer_count,
|
||||
}
|
||||
return render(request, 'jobs/job_detail.html', context)
|
||||
\
|
||||
|
||||
|
||||
# job detail facing the candidate:
|
||||
def job_detail_candidate(request,slug):
|
||||
job=get_object_or_404(JobPosting,slug=slug)
|
||||
return render(request,'jobs/job_detail_candidate.html',{'job':job})
|
||||
|
||||
def post_to_linkedin(request,slug):
|
||||
"""Post a job to LinkedIn"""
|
||||
|
||||
230
templates/jobs/job_detail_candidate.html
Normal file
230
templates/jobs/job_detail_candidate.html
Normal file
@ -0,0 +1,230 @@
|
||||
{% 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-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>
|
||||
|
||||
{% if job.form_template %}
|
||||
<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 %}
|
||||
|
||||
{% 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">
|
||||
|
||||
<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>
|
||||
{% 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>
|
||||
|
||||
{% if job.description %}
|
||||
<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 %}
|
||||
<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 %}
|
||||
<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 %}
|
||||
<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>
|
||||
|
||||
<div class="mobile-fixed-apply-bar d-lg-none">
|
||||
{% if job.form_template %}
|
||||
<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 %}
|
||||
Loading…
x
Reference in New Issue
Block a user