safe filter
This commit is contained in:
parent
3b8ed4c93b
commit
53318a998c
Binary file not shown.
@ -120,6 +120,8 @@ DATABASES = {
|
|||||||
# Password validation
|
# Password validation
|
||||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AUTH_PASSWORD_VALIDATORS = [
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||||
|
|||||||
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.
@ -5,7 +5,7 @@ from django.utils import timezone
|
|||||||
from .models import (
|
from .models import (
|
||||||
JobPosting, Candidate, TrainingMaterial, ZoomMeeting,
|
JobPosting, Candidate, TrainingMaterial, ZoomMeeting,
|
||||||
FormTemplate, FormStage, FormField, FormSubmission, FieldResponse,
|
FormTemplate, FormStage, FormField, FormSubmission, FieldResponse,
|
||||||
SharedFormTemplate, Source, HiringAgency, IntegrationLog,InterviewSchedule
|
SharedFormTemplate, Source, HiringAgency, IntegrationLog,InterviewSchedule,Profile
|
||||||
)
|
)
|
||||||
|
|
||||||
class FormFieldInline(admin.TabularInline):
|
class FormFieldInline(admin.TabularInline):
|
||||||
@ -261,4 +261,5 @@ admin.site.register(FormStage)
|
|||||||
admin.site.register(FormField)
|
admin.site.register(FormField)
|
||||||
admin.site.register(FieldResponse)
|
admin.site.register(FieldResponse)
|
||||||
admin.site.register(InterviewSchedule)
|
admin.site.register(InterviewSchedule)
|
||||||
|
admin.site.register(Profile)
|
||||||
# admin.site.register(HiringAgency)
|
# admin.site.register(HiringAgency)
|
||||||
|
|||||||
@ -259,8 +259,9 @@ class JobPostingForm(forms.ModelForm):
|
|||||||
'type': 'date'
|
'type': 'date'
|
||||||
}),
|
}),
|
||||||
'application_instructions': SummernoteWidget(attrs={
|
'application_instructions': SummernoteWidget(attrs={
|
||||||
# Removed 'class' and 'rows'
|
|
||||||
'placeholder': 'Special instructions for applicants (e.g., required documents, reference requirements, etc.)'
|
'placeholder': 'Special instructions for applicants (e.g., required documents, reference requirements, etc.)',
|
||||||
|
|
||||||
}),
|
}),
|
||||||
'open_positions': forms.NumberInput(attrs={
|
'open_positions': forms.NumberInput(attrs={
|
||||||
'class': 'form-control',
|
'class': 'form-control',
|
||||||
|
|||||||
24
recruitment/migrations/0027_profile.py
Normal file
24
recruitment/migrations/0027_profile.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Generated by Django 5.2.7 on 2025-10-08 13:01
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('recruitment', '0026_interviewschedule_scheduledinterview'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Profile',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('profile_image', models.ImageField(blank=True, null=True, upload_to='profile_pic/')),
|
||||||
|
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -9,6 +9,9 @@ from django.core.exceptions import ValidationError
|
|||||||
from django_countries.fields import CountryField
|
from django_countries.fields import CountryField
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
|
class Profile(models.Model):
|
||||||
|
profile_image=models.ImageField(null=True,blank=True,upload_to='profile_pic/')
|
||||||
|
user=models.OneToOneField(User,on_delete=models.CASCADE,related_name='profile')
|
||||||
class Base(models.Model):
|
class Base(models.Model):
|
||||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_('Created at'))
|
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_('Created at'))
|
||||||
updated_at = models.DateTimeField(auto_now=True, verbose_name=_('Updated at'))
|
updated_at = models.DateTimeField(auto_now=True, verbose_name=_('Updated at'))
|
||||||
|
|||||||
@ -83,8 +83,7 @@ class ZoomMeetingListView(ListView):
|
|||||||
if search_query:
|
if search_query:
|
||||||
queryset = queryset.filter(
|
queryset = queryset.filter(
|
||||||
Q(topic__icontains=search_query) |
|
Q(topic__icontains=search_query) |
|
||||||
Q(meeting_id__icontains=search_query) |
|
Q(meeting_id__icontains=search_query)
|
||||||
Q(host_email__icontains=search_query)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
@ -143,27 +142,30 @@ def ZoomMeetingDeleteView(request, pk):
|
|||||||
|
|
||||||
|
|
||||||
#Job Posting
|
#Job Posting
|
||||||
def job_list(request):
|
# def job_list(request):
|
||||||
"""Display the list of job postings order by creation date descending"""
|
# """Display the list of job postings order by creation date descending"""
|
||||||
jobs=JobPosting.objects.all().order_by('-created_at')
|
# jobs=JobPosting.objects.all().order_by('-created_at')
|
||||||
|
|
||||||
# Filter by status if provided
|
# # Filter by status if provided
|
||||||
status=request.GET.get('status')
|
# print(f"the request is: {request} ")
|
||||||
if status:
|
# status=request.GET.get('status')
|
||||||
jobs=jobs.filter(status=status)
|
# print(f"DEBUG: Status filter received: {status}")
|
||||||
|
# if status:
|
||||||
|
# jobs=jobs.filter(status=status)
|
||||||
|
|
||||||
#pagination
|
# #pagination
|
||||||
paginator=Paginator(jobs,10) # Show 10 jobs per page
|
# paginator=Paginator(jobs,10) # Show 10 jobs per page
|
||||||
page_number=request.GET.get('page')
|
# page_number=request.GET.get('page')
|
||||||
page_obj=paginator.get_page(page_number)
|
# page_obj=paginator.get_page(page_number)
|
||||||
return render(request, 'jobs/job_list.html', {
|
# return render(request, 'jobs/job_list.html', {
|
||||||
'page_obj': page_obj,
|
# 'page_obj': page_obj,
|
||||||
'status_filter': status
|
# 'status_filter': status
|
||||||
})
|
# })
|
||||||
|
|
||||||
|
|
||||||
def create_job(request):
|
def create_job(request):
|
||||||
"""Create a new job posting"""
|
"""Create a new job posting"""
|
||||||
|
|
||||||
if request.method=='POST':
|
if request.method=='POST':
|
||||||
|
|
||||||
form=JobPostingForm(request.POST,is_anonymous_user=not request.user.is_authenticated)
|
form=JobPostingForm(request.POST,is_anonymous_user=not request.user.is_authenticated)
|
||||||
@ -761,7 +763,8 @@ def delete_form_template(request, template_id):
|
|||||||
def form_wizard_view(request, template_id):
|
def form_wizard_view(request, template_id):
|
||||||
"""Display the form as a step-by-step wizard"""
|
"""Display the form as a step-by-step wizard"""
|
||||||
template = get_object_or_404(FormTemplate, id=template_id, is_active=True)
|
template = get_object_or_404(FormTemplate, id=template_id, is_active=True)
|
||||||
return render(request, 'forms/form_wizard.html', {'template_id': template_id})
|
job_id=template.job.internal_job_id
|
||||||
|
return render(request, 'forms/form_wizard.html', {'template_id': template_id,'job_id':job_id})
|
||||||
@require_http_methods(["POST"])
|
@require_http_methods(["POST"])
|
||||||
def submit_form(request, template_id):
|
def submit_form(request, template_id):
|
||||||
"""Handle form submission"""
|
"""Handle form submission"""
|
||||||
|
|||||||
@ -41,10 +41,15 @@ class JobListView(LoginRequiredMixin, ListView):
|
|||||||
# Filter for non-staff users
|
# Filter for non-staff users
|
||||||
if not self.request.user.is_staff:
|
if not self.request.user.is_staff:
|
||||||
queryset = queryset.filter(status='Published')
|
queryset = queryset.filter(status='Published')
|
||||||
|
|
||||||
|
status=self.request.GET.get('status')
|
||||||
|
if status:
|
||||||
|
queryset=queryset.filter(status=status)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
|
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context['search_query'] = self.request.GET.get('search', '')
|
context['search_query'] = self.request.GET.get('search', '')
|
||||||
context['lang'] = get_language()
|
context['lang'] = get_language()
|
||||||
@ -288,7 +293,7 @@ class TrainingListView(LoginRequiredMixin, ListView):
|
|||||||
template_name = 'recruitment/training_list.html'
|
template_name = 'recruitment/training_list.html'
|
||||||
context_object_name = 'materials'
|
context_object_name = 'materials'
|
||||||
paginate_by = 10
|
paginate_by = 10
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
queryset = super().get_queryset()
|
queryset = super().get_queryset()
|
||||||
|
|
||||||
@ -296,8 +301,7 @@ class TrainingListView(LoginRequiredMixin, ListView):
|
|||||||
search_query = self.request.GET.get('search', '')
|
search_query = self.request.GET.get('search', '')
|
||||||
if search_query:
|
if search_query:
|
||||||
queryset = queryset.filter(
|
queryset = queryset.filter(
|
||||||
Q(title__icontains=search_query) |
|
Q(title__icontains=search_query)
|
||||||
Q(description__icontains=search_query)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Filter for non-staff users
|
# Filter for non-staff users
|
||||||
|
|||||||
@ -320,11 +320,13 @@
|
|||||||
<li class="nav-item me-2">
|
<li class="nav-item me-2">
|
||||||
<a class="nav-link {% if request.resolver_match.url_name == 'form_templates_list' %}active{% endif %}" href="{% url 'form_templates_list' %}">
|
<a class="nav-link {% if request.resolver_match.url_name == 'form_templates_list' %}active{% endif %}" href="{% url 'form_templates_list' %}">
|
||||||
<span class="d-flex align-items-center gap-2">
|
<span class="d-flex align-items-center gap-2">
|
||||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||||
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" stroke="currentColor" stroke-width="2"></path>
|
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
{% trans "Form Templates" %}
|
{% trans "Form Templates" %}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown ms-2">
|
<li class="nav-item dropdown ms-2">
|
||||||
@ -389,21 +391,35 @@
|
|||||||
data-bs-auto-close="outside"
|
data-bs-auto-close="outside"
|
||||||
data-bs-offset="0, 8"
|
data-bs-offset="0, 8"
|
||||||
>
|
>
|
||||||
<div class="profile-avatar" title="{% trans 'Your account' %}">
|
{% if user.profile.profile_image %}
|
||||||
{{ user.username|first|upper }}
|
<img src="{{ user.profile.profile_image.url }}" alt="{{ user.username }}" class="profile-avatar"
|
||||||
</div>
|
style="width: 36px; height: 36px; object-fit: cover; background-color: var(--kaauh-teal); display: inline-block; vertical-align: middle;"
|
||||||
|
title="{% trans 'Your account' %}">
|
||||||
|
{% else %}
|
||||||
|
<div class="profile-avatar" title="{% trans 'Your account' %}">
|
||||||
|
{{ user.username|first|upper }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% comment %} <span class="ms-2 d-none d-lg-inline fw-semibold">{{ user.username }}</span> {% endcomment %}
|
||||||
</button>
|
</button>
|
||||||
<ul
|
<ul
|
||||||
class="dropdown-menu dropdown-menu-end py-0 shadow border-0 rounded-3"
|
class="dropdown-menu dropdown-menu-end py-0 shadow border-0 rounded-3"
|
||||||
data-bs-popper="static"
|
data-bs-popper="static"
|
||||||
style="min-width: 240px;"
|
style="min-width: 240px;"
|
||||||
>
|
>
|
||||||
<li class="px-4 py-3 bg-dark-subtle">
|
<li class="px-4 py-3 ">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div class="me-3">
|
<div class="me-3 d-flex align-items-center justify-content-center" style="min-width: 48px;">
|
||||||
<div class="profile-avatar" style="width: 44px; height: 44px; background-color: var(--kaauh-teal);">
|
{% if user.profile.profile_image %}
|
||||||
{{ user.username|first|upper }}
|
<img src="{{ user.profile.profile_image.url }}" alt="{{ user.username }}" class="profile-avatar shadow-sm border"
|
||||||
</div>
|
style="width: 44px; height: 44px; object-fit: cover; background-color: var(--kaauh-teal); display: block;"
|
||||||
|
title="{% trans 'Your account' %}">
|
||||||
|
{% else %}
|
||||||
|
<div class="profile-avatar shadow-sm border d-flex align-items-center justify-content-center"
|
||||||
|
style="width: 44px; height: 44px; background-color: var(--kaauh-teal); font-size: 1.2rem;">
|
||||||
|
{{ user.username|first|upper }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="fw-semibold text-dark">{{ user.get_full_name|default:user.username }}</div>
|
<div class="fw-semibold text-dark">{{ user.get_full_name|default:user.username }}</div>
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
{% load static i18n %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
@ -685,8 +686,11 @@
|
|||||||
<!-- Sidebar with form elements -->
|
<!-- Sidebar with form elements -->
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<div class="sidebar-header">
|
<div class="sidebar-header">
|
||||||
<a class="" href="{% url 'form_templates_list' %}"></a>
|
<a class="" href="{% url 'form_templates_list' %}">
|
||||||
<h2><i class="fas fa-cube"></i> Form Elements</h2>
|
<img src="{% static 'image/kaauh.jpeg' %}" style="height:100px; width:100px;">
|
||||||
|
|
||||||
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="field-categories">
|
<div class="field-categories">
|
||||||
<div class="field-category">
|
<div class="field-category">
|
||||||
|
|||||||
@ -476,11 +476,15 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link text-secondary" href="/profile/">{% translate "Profile" %}</a>
|
<a class="nav-link text-secondary" href="/profile/">{% translate "Profile" %}</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link text-secondary" href="https://kaauh.edu.sa/career">{% translate "Careers" %}</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<nav id="bottomNavbar" class="navbar navbar-expand-lg sticky-top" style="background-color: var(--kaauh-teal); z-index: 1030;">
|
<nav id="bottomNavbar" class="navbar navbar-expand-lg sticky-top" style="background-color: var(--kaauh-teal); z-index: 1030;">
|
||||||
|
<span class="ms-2 text-white">JOB ID: {{job_id}}</span>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="page-content-wrapper">
|
<div class="page-content-wrapper">
|
||||||
|
|||||||
@ -161,7 +161,7 @@
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div>
|
<div>
|
||||||
<label for="{{ form.description.id_for_label }}" class="form-label">{% trans "Job Description" %} <span class="text-danger">*</span></label>
|
<label for="{{ form.description.id_for_label }}" class="form-label">{% trans "Job Description" %} <span class="text-danger">*</span></label>
|
||||||
{{ form.description }}
|
{{ form.description}}
|
||||||
{% if form.description.errors %}<div class="text-danger small mt-1">{{ form.description.errors }}</div>{% endif %}
|
{% if form.description.errors %}<div class="text-danger small mt-1">{{ form.description.errors }}</div>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -169,7 +169,7 @@
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div>
|
<div>
|
||||||
<label for="{{ form.qualifications.id_for_label }}" class="form-label">{% trans "Qualifications and Requirements" %}</label>
|
<label for="{{ form.qualifications.id_for_label }}" class="form-label">{% trans "Qualifications and Requirements" %}</label>
|
||||||
{{ form.qualifications }}
|
{{ form.qualifications}}
|
||||||
{% if form.qualifications.errors %}<div class="text-danger small mt-1">{{ form.qualifications.errors }}</div>{% endif %}
|
{% if form.qualifications.errors %}<div class="text-danger small mt-1">{{ form.qualifications.errors }}</div>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -339,19 +339,19 @@
|
|||||||
{% if job.description %}
|
{% if job.description %}
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<h5>{% trans "Job Description" %}</h5>
|
<h5>{% trans "Job Description" %}</h5>
|
||||||
<div class="text-secondary">{{ job.description|linebreaks }}</div>
|
<div class="text-secondary">{{ job.description|safe }}</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if job.qualifications %}
|
{% if job.qualifications %}
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<h5>{% trans "Required Qualifications" %}</h5>
|
<h5>{% trans "Required Qualifications" %}</h5>
|
||||||
<div class="text-secondary">{{ job.qualifications|linebreaks }}</div>
|
<div class="text-secondary">{{ job.qualifications|safe }}</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if job.benefits %}
|
{% if job.benefits %}
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<h5>{% trans "Benefits" %}</h5>
|
<h5>{% trans "Benefits" %}</h5>
|
||||||
<div class="text-secondary">{{ job.benefits|linebreaks }}</div>
|
<div class="text-secondary">{{ job.benefits|safe}}</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
@ -361,7 +361,7 @@
|
|||||||
<div class="tab-pane fade" id="instructions" role="tabpanel" aria-labelledby="instructions-tab">
|
<div class="tab-pane fade" id="instructions" role="tabpanel" aria-labelledby="instructions-tab">
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<h5>{% trans "Application Instructions" %}</h5>
|
<h5>{% trans "Application Instructions" %}</h5>
|
||||||
<div class="text-secondary">{{ job.application_instructions|linebreaks }}</div>
|
<div class="text-secondary">{{ job.application_instructions|safe }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -526,7 +526,7 @@
|
|||||||
{% trans "Manage the custom application forms associated with this job posting." %}
|
{% trans "Manage the custom application forms associated with this job posting." %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<a href="" class="btn btn-main-action">
|
<a href="{% url 'create_form_template' %}" class="btn btn-main-action">
|
||||||
<i class="fas fa-plus-circle me-2"></i> {% trans "Create New Form" %}
|
<i class="fas fa-plus-circle me-2"></i> {% trans "Create New Form" %}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@ -534,9 +534,9 @@
|
|||||||
<i class="fas fa-list-alt me-1"></i> {% trans "View All Existing Forms" %}
|
<i class="fas fa-list-alt me-1"></i> {% trans "View All Existing Forms" %}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{% url 'candidate_create_for_job' job.slug %}" class="btn btn-success me-2">
|
<a href="{% url 'candidate_create_for_job' job.slug %}" class="btn btn-main-action">
|
||||||
<i class="fas fa-user-plus"></i> {% trans "Create Candidate" %}
|
<i class="fas fa-user-plus"></i> {% trans "Create Candidate" %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -151,6 +151,9 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link text-secondary" href="/profile/">{% translate "Profile" %}</a>
|
<a class="nav-link text-secondary" href="/profile/">{% translate "Profile" %}</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link text-secondary" href="https://kaauh.edu.sa/career">{% translate "Careers" %}</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -233,10 +236,10 @@
|
|||||||
{% comment %} <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> {% endcomment %}
|
{% comment %} <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> {% endcomment %}
|
||||||
</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.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|safe }}</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.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|safe }}</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.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|safe }}</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 %}
|
{% 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|safe }}</div></div>{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -123,25 +123,26 @@
|
|||||||
|
|
||||||
<div class="card mb-4 shadow-sm no-hover">
|
<div class="card mb-4 shadow-sm no-hover">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title text-muted mb-3" style="font-weight: 500;">Filter & Search</h5>
|
<div class="row">
|
||||||
<form method="get" class="row g-3 align-items-end">
|
|
||||||
|
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label for="search" class="form-label small text-muted">Search by Title or Department</label>
|
<label for="search" class="form-label small text-muted">Search by Title or Department</label>
|
||||||
<div class="input-group input-group-lg">
|
<div class="input-group input-group-lg mb-3">
|
||||||
<span class="input-group-text bg-white border-end-0"><i class="fas fa-search text-muted"></i></span>
|
<form method="get" action="" class="w-100">
|
||||||
<input type="text" name="q" id="search" class="form-control form-control-search border-start-0"
|
{% include 'includes/search_form.html' %}
|
||||||
placeholder="e.g., 'Professor' or 'Marketing'"
|
</form>
|
||||||
value="{{ search_query|default_if_none:'' }}">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
{% url 'job_list' as job_list_url %}
|
||||||
|
|
||||||
|
<form method="GET" class="row g-3 align-items-end" >
|
||||||
|
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<label for="status" class="form-label small text-muted">Filter by Status</label>
|
<label for="status" class="form-label small text-muted">Filter by Status</label>
|
||||||
<select name="status" id="status" class="form-select form-select-sm">
|
<select name="status" id="status" class="form-select form-select-sm">
|
||||||
<option value="">All Statuses</option>
|
<option value="">All Statuses</option>
|
||||||
<option value="DRAFT" {% if status_filter == 'DRAFT' %}selected{% endif %}>Draft</option>
|
<option value="DRAFT" {% if status_filter == 'DRAFT' %}selected{% endif %}>Draft</option>
|
||||||
<option value="ACTIVE" {% if status_filter == 'ACTIVE' %}selected{% endif %}>Active</option>
|
<option value="PUBLISHED" {% if status_filter == 'PUBLISHED' %}selected{% endif %}>Published</option>
|
||||||
<option value="CLOSED" {% if status_filter == 'CLOSED' %}selected{% endif %}>Closed</option>
|
<option value="CLOSED" {% if status_filter == 'CLOSED' %}selected{% endif %}>Closed</option>
|
||||||
<option value="ARCHIVED" {% if status_filter == 'ARCHIVED' %}selected{% endif %}>Archived</option>
|
<option value="ARCHIVED" {% if status_filter == 'ARCHIVED' %}selected{% endif %}>Archived</option>
|
||||||
</select>
|
</select>
|
||||||
@ -152,17 +153,13 @@
|
|||||||
<button type="submit" class="btn btn-main-action btn-lg">
|
<button type="submit" class="btn btn-main-action btn-lg">
|
||||||
<i class="fas fa-filter me-1"></i> Apply Filters
|
<i class="fas fa-filter me-1"></i> Apply Filters
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{# Show Clear button if any filter/search is active #}
|
|
||||||
{% if status_filter or search_query %}
|
|
||||||
<a href="{% url 'job_list' %}" class="btn btn-outline-danger btn-sm">
|
|
||||||
<i class="fas fa-times me-1"></i> Clear Filters
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user