updated the trans in some templtaes which were missing an drop the extra pagination
This commit is contained in:
parent
667b4c45f2
commit
34b34b9994
6
.env
6
.env
@ -1,3 +1,3 @@
|
||||
DB_NAME=norahuniversity
|
||||
DB_USER=norahuniversity
|
||||
DB_PASSWORD=norahuniversity
|
||||
DB_NAME=haikal_db
|
||||
DB_USER=faheed
|
||||
DB_PASSWORD=Faheed@215
|
||||
@ -209,31 +209,31 @@ ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True
|
||||
ACCOUNT_FORMS = {"signup": "recruitment.forms.StaffSignupForm"}
|
||||
|
||||
|
||||
# MAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
||||
# EMAIL_HOST = "10.10.1.110"
|
||||
# EMAIL_PORT = 2225
|
||||
MAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
||||
EMAIL_HOST = "10.10.1.110"
|
||||
EMAIL_PORT = 2225
|
||||
# EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
||||
|
||||
EMAIL_HOST_PASSWORD = os.getenv("EMAIL_PASSWORD", "mssp.0Q0rSwb.zr6ke4n2k3e4on12.aHwJqnI")
|
||||
EMAIL_HOST = "smtp.mailersend.net"
|
||||
EMAIL_PORT = 2525
|
||||
EMAIL_HOST_USER = "MS_lhygCJ@test-65qngkd8nx3lwr12.mlsender.net"
|
||||
EMAIL_HOST_PASSWORD = "mssp.0Q0rSwb.zr6ke4n2k3e4on12.aHwJqnI"
|
||||
EMAIL_USE_TLS = True
|
||||
EMAIL_HOST = 'sandbox.smtp.mailtrap.io'
|
||||
EMAIL_HOST_USER = '38e5179debe69a'
|
||||
EMAIL_HOST_PASSWORD = 'ffa75647d01ecb'
|
||||
EMAIL_PORT = '2525'
|
||||
# EMAIL_HOST_PASSWORD = os.getenv("EMAIL_PASSWORD", "mssp.0Q0rSwb.zr6ke4n2k3e4on12.aHwJqnI")
|
||||
# EMAIL_HOST = "smtp.mailersend.net"
|
||||
# EMAIL_PORT = 2525
|
||||
# EMAIL_HOST_USER = "MS_lhygCJ@test-65qngkd8nx3lwr12.mlsender.net"
|
||||
# EMAIL_HOST_PASSWORD = "mssp.0Q0rSwb.zr6ke4n2k3e4on12.aHwJqnI"
|
||||
# EMAIL_USE_TLS = True
|
||||
# EMAIL_HOST = 'sandbox.smtp.mailtrap.io'
|
||||
# EMAIL_HOST_USER = '38e5179debe69a'
|
||||
# EMAIL_HOST_PASSWORD = 'ffa75647d01ecb'
|
||||
# EMAIL_PORT = '2525'
|
||||
|
||||
|
||||
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
EMAIL_HOST = 'smtp.gmail.com'
|
||||
EMAIL_PORT = 587
|
||||
EMAIL_USE_TLS = True
|
||||
EMAIL_HOST_USER = 'faheedk215@gmail.com' # Use your actual Gmail email address
|
||||
EMAIL_HOST_PASSWORD = 'nfxf xpzo bpsb lqje' #
|
||||
DEFAULT_FROM_EMAIL='faheedlearn@gmail.com'
|
||||
# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
# EMAIL_HOST = 'smtp.gmail.com'
|
||||
# EMAIL_PORT = 587
|
||||
# EMAIL_USE_TLS = True
|
||||
# EMAIL_HOST_USER = 'faheedk215@gmail.com' # Use your actual Gmail email address
|
||||
# EMAIL_HOST_PASSWORD = 'nfxf xpzo bpsb lqje' #
|
||||
# DEFAULT_FROM_EMAIL='faheedlearn@gmail.com'
|
||||
|
||||
# Crispy Forms Configuration
|
||||
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
|
||||
|
||||
@ -1308,8 +1308,9 @@ def delete_form_template(request, template_id):
|
||||
def application_submit_form(request, slug):
|
||||
"""Display the form as a step-by-step wizard"""
|
||||
job = get_object_or_404(JobPosting, slug=slug)
|
||||
template_slug=job.form_template.slug
|
||||
if not request.user.is_authenticated:
|
||||
return redirect("application_signup", slug=slug)
|
||||
return redirect("application_signup", slug=template_slug)
|
||||
|
||||
if request.user.user_type == "candidate":
|
||||
person = request.user.person_profile
|
||||
@ -2432,8 +2433,11 @@ def create_staff_user(request):
|
||||
@superuser_required
|
||||
def admin_settings(request):
|
||||
staffs = User.objects.filter(user_type="staff", is_superuser=False)
|
||||
paginator=Paginator(staffs,20)
|
||||
page_number=request.GET.get('page')
|
||||
page_obj=paginator.get_page(page_number)
|
||||
form = ToggleAccountForm()
|
||||
context = {"staffs": staffs, "form": form}
|
||||
context = {"staffs": page_obj, "form": form,"page_obj":page_obj}
|
||||
return render(request, "user/admin_settings.html", context)
|
||||
|
||||
|
||||
@ -2769,7 +2773,7 @@ def agency_assignment_list(request):
|
||||
assignments = assignments.filter(status=status_filter)
|
||||
|
||||
# Pagination
|
||||
paginator = Paginator(assignments, 15) # Show 15 assignments per page
|
||||
paginator = Paginator(assignments, 20) # Show 15 assignments per page
|
||||
page_number = request.GET.get("page")
|
||||
page_obj = paginator.get_page(page_number)
|
||||
|
||||
@ -4514,133 +4518,133 @@ def api_application_detail(request, candidate_id):
|
||||
|
||||
|
||||
# Source CRUD Views
|
||||
@login_required
|
||||
@staff_user_required
|
||||
def source_list(request):
|
||||
"""List all sources with search and pagination"""
|
||||
search_query = request.GET.get("q", "")
|
||||
sources = Source.objects.all()
|
||||
# @login_required
|
||||
# @staff_user_required
|
||||
# def source_list(request):
|
||||
# """List all sources with search and pagination"""
|
||||
# search_query = request.GET.get("q", "")
|
||||
# sources = Source.objects.all()
|
||||
|
||||
if search_query:
|
||||
sources = sources.filter(
|
||||
Q(name__icontains=search_query)
|
||||
| Q(source_type__icontains=search_query)
|
||||
| Q(description__icontains=search_query)
|
||||
)
|
||||
# if search_query:
|
||||
# sources = sources.filter(
|
||||
# Q(name__icontains=search_query)
|
||||
# | Q(source_type__icontains=search_query)
|
||||
# | Q(description__icontains=search_query)
|
||||
# )
|
||||
|
||||
# Order by most recently created
|
||||
sources = sources.order_by("-created_at")
|
||||
# # Order by most recently created
|
||||
# sources = sources.order_by("-created_at")
|
||||
|
||||
# Pagination
|
||||
paginator = Paginator(sources, 1) # Show 15 sources per page
|
||||
page_number = request.GET.get("page")
|
||||
page_obj = paginator.get_page(page_number)
|
||||
# # Pagination
|
||||
# paginator = Paginator(sources, 1) # Show 15 sources per page
|
||||
# page_number = request.GET.get("page")
|
||||
# page_obj = paginator.get_page(page_number)
|
||||
|
||||
context = {
|
||||
"page_obj": page_obj,
|
||||
"search_query": search_query,
|
||||
"total_sources": sources.count(),
|
||||
}
|
||||
return render(request, "recruitment/source_list.html", context)
|
||||
# context = {
|
||||
# "page_obj": page_obj,
|
||||
# "search_query": search_query,
|
||||
# "total_sources": sources.count(),
|
||||
# }
|
||||
# return render(request, "recruitment/source_list.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@staff_user_required
|
||||
def source_create(request):
|
||||
"""Create a new source"""
|
||||
if request.method == "POST":
|
||||
form = SourceForm(request.POST)
|
||||
if form.is_valid():
|
||||
source = form.save()
|
||||
messages.success(request, f'Source "{source.name}" created successfully!')
|
||||
return redirect("source_detail", slug=source.slug)
|
||||
else:
|
||||
messages.error(request, "Please correct the errors below.")
|
||||
else:
|
||||
form = SourceForm()
|
||||
# @login_required
|
||||
# @staff_user_required
|
||||
# def source_create(request):
|
||||
# """Create a new source"""
|
||||
# if request.method == "POST":
|
||||
# form = SourceForm(request.POST)
|
||||
# if form.is_valid():
|
||||
# source = form.save()
|
||||
# messages.success(request, f'Source "{source.name}" created successfully!')
|
||||
# return redirect("source_detail", slug=source.slug)
|
||||
# else:
|
||||
# messages.error(request, "Please correct the errors below.")
|
||||
# else:
|
||||
# form = SourceForm()
|
||||
|
||||
context = {
|
||||
"form": form,
|
||||
"title": "Create New Source",
|
||||
"button_text": "Create Source",
|
||||
}
|
||||
return render(request, "recruitment/source_form.html", context)
|
||||
# context = {
|
||||
# "form": form,
|
||||
# "title": "Create New Source",
|
||||
# "button_text": "Create Source",
|
||||
# }
|
||||
# return render(request, "recruitment/source_form.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@staff_user_required
|
||||
def source_detail(request, slug):
|
||||
"""View details of a specific source"""
|
||||
source = get_object_or_404(Source, slug=slug)
|
||||
# @login_required
|
||||
# @staff_user_required
|
||||
# def source_detail(request, slug):
|
||||
# """View details of a specific source"""
|
||||
# source = get_object_or_404(Source, slug=slug)
|
||||
|
||||
# Get integration logs for this source
|
||||
integration_logs = source.integration_logs.order_by("-created_at")[
|
||||
:10
|
||||
] # Show recent 10 logs
|
||||
# # Get integration logs for this source
|
||||
# integration_logs = source.integration_logs.order_by("-created_at")[
|
||||
# :10
|
||||
# ] # Show recent 10 logs
|
||||
|
||||
# Statistics
|
||||
total_logs = source.integration_logs.count()
|
||||
successful_logs = source.integration_logs.filter(method="POST").count()
|
||||
failed_logs = source.integration_logs.filter(
|
||||
method="POST", status_code__gte=400
|
||||
).count()
|
||||
# # Statistics
|
||||
# total_logs = source.integration_logs.count()
|
||||
# successful_logs = source.integration_logs.filter(method="POST").count()
|
||||
# failed_logs = source.integration_logs.filter(
|
||||
# method="POST", status_code__gte=400
|
||||
# ).count()
|
||||
|
||||
context = {
|
||||
"source": source,
|
||||
"integration_logs": integration_logs,
|
||||
"total_logs": total_logs,
|
||||
"successful_logs": successful_logs,
|
||||
"failed_logs": failed_logs,
|
||||
}
|
||||
return render(request, "recruitment/source_detail.html", context)
|
||||
# context = {
|
||||
# "source": source,
|
||||
# "integration_logs": integration_logs,
|
||||
# "total_logs": total_logs,
|
||||
# "successful_logs": successful_logs,
|
||||
# "failed_logs": failed_logs,
|
||||
# }
|
||||
# return render(request, "recruitment/source_detail.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@staff_user_required
|
||||
def source_update(request, slug):
|
||||
"""Update an existing source"""
|
||||
source = get_object_or_404(Source, slug=slug)
|
||||
# @login_required
|
||||
# @staff_user_required
|
||||
# def source_update(request, slug):
|
||||
# """Update an existing source"""
|
||||
# source = get_object_or_404(Source, slug=slug)
|
||||
|
||||
if request.method == "POST":
|
||||
form = SourceForm(request.POST, instance=source)
|
||||
if form.is_valid():
|
||||
source = form.save()
|
||||
messages.success(request, f'Source "{source.name}" updated successfully!')
|
||||
return redirect("source_detail", slug=source.slug)
|
||||
else:
|
||||
messages.error(request, "Please correct the errors below.")
|
||||
else:
|
||||
form = SourceForm(instance=source)
|
||||
# if request.method == "POST":
|
||||
# form = SourceForm(request.POST, instance=source)
|
||||
# if form.is_valid():
|
||||
# source = form.save()
|
||||
# messages.success(request, f'Source "{source.name}" updated successfully!')
|
||||
# return redirect("source_detail", slug=source.slug)
|
||||
# else:
|
||||
# messages.error(request, "Please correct the errors below.")
|
||||
# else:
|
||||
# form = SourceForm(instance=source)
|
||||
|
||||
context = {
|
||||
"form": form,
|
||||
"source": source,
|
||||
"title": _("Edit Source: %(name)s") % {"name": source.name},
|
||||
"button_text": _("Update Source"),
|
||||
}
|
||||
return render(request, "recruitment/source_form.html", context)
|
||||
# context = {
|
||||
# "form": form,
|
||||
# "source": source,
|
||||
# "title": _("Edit Source: %(name)s") % {"name": source.name},
|
||||
# "button_text": _("Update Source"),
|
||||
# }
|
||||
# return render(request, "recruitment/source_form.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@staff_user_required
|
||||
def source_delete(request, slug):
|
||||
"""Delete a source"""
|
||||
source = get_object_or_404(Source, slug=slug)
|
||||
# @login_required
|
||||
# @staff_user_required
|
||||
# def source_delete(request, slug):
|
||||
# """Delete a source"""
|
||||
# source = get_object_or_404(Source, slug=slug)
|
||||
|
||||
if request.method == "POST":
|
||||
source_name = source.name
|
||||
source.delete()
|
||||
messages.success(request, f'Source "{source_name}" deleted successfully!')
|
||||
return redirect("source_list")
|
||||
# if request.method == "POST":
|
||||
# source_name = source.name
|
||||
# source.delete()
|
||||
# messages.success(request, f'Source "{source_name}" deleted successfully!')
|
||||
# return redirect("source_list")
|
||||
|
||||
context = {
|
||||
"source": source,
|
||||
"title": _("Delete Source: %(name)s") % {"name": source.name},
|
||||
"message": _('Are you sure you want to delete the source "%(name)s"?')
|
||||
% {"name": source.name},
|
||||
"cancel_url": reverse("source_detail", kwargs={"slug": source.slug}),
|
||||
}
|
||||
return render(request, "recruitment/source_confirm_delete.html", context)
|
||||
# context = {
|
||||
# "source": source,
|
||||
# "title": _("Delete Source: %(name)s") % {"name": source.name},
|
||||
# "message": _('Are you sure you want to delete the source "%(name)s"?')
|
||||
# % {"name": source.name},
|
||||
# "cancel_url": reverse("source_detail", kwargs={"slug": source.slug}),
|
||||
# }
|
||||
# return render(request, "recruitment/source_confirm_delete.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@ -5379,7 +5383,7 @@ class JobListView(LoginRequiredMixin, StaffRequiredMixin, ListView):
|
||||
model = JobPosting
|
||||
template_name = "jobs/job_list.html"
|
||||
context_object_name = "jobs"
|
||||
paginate_by = 10
|
||||
paginate_by = 20
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = super().get_queryset().order_by("-created_at")
|
||||
@ -5507,8 +5511,8 @@ class ApplicationListView(LoginRequiredMixin, StaffRequiredMixin, ListView):
|
||||
queryset = queryset.filter(job__slug=job)
|
||||
if stage:
|
||||
queryset = queryset.filter(stage=stage)
|
||||
|
||||
return queryset.order_by("-created_at")
|
||||
queryset=queryset.order_by("-created_at")
|
||||
return queryset
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
--kaauh-info: #17a2b8;
|
||||
--kaauh-danger: #dc3545;
|
||||
--kaauh-warning: #ffc107;
|
||||
--kaauh-border: #eaeff3;
|
||||
}
|
||||
|
||||
/* Primary Color Overrides */
|
||||
@ -733,5 +734,47 @@ html[dir="rtl"] .me-auto { margin-right: 0 !important; margin-left: auto !import
|
||||
color: var(--kaauh-teal);
|
||||
}
|
||||
|
||||
/* --- Pagination Base Styles --- */
|
||||
.pagination .page-link {
|
||||
color: var(--kaauh-teal); /* Teal text for links */
|
||||
border-color: var(--kaauh-border); /* Light border */
|
||||
background-color: #fff;
|
||||
font-weight: 500;
|
||||
font-size: 0.9rem;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
/* --- Hover State --- */
|
||||
.pagination .page-link:hover {
|
||||
color: var(--kaauh-teal-dark); /* Darker teal text on hover */
|
||||
background-color: var(--kaauh-gray-light);
|
||||
border-color: var(--kaauh-border);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* --- Active State (Current Page) --- */
|
||||
/* This targets the <li class="active"> and overrides the inner span */
|
||||
.pagination .page-item.active .page-link {
|
||||
background-color: var(--kaauh-teal);
|
||||
border-color: var(--kaauh-teal);
|
||||
color: #ffffff;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
/* --- Focus State (Accessibility) --- */
|
||||
/* Replaces the default blue glow with a teal glow */
|
||||
.pagination .page-link:focus {
|
||||
box-shadow: 0 0 0 0.25rem rgba(0, 99, 110, 0.25);
|
||||
background-color: var(--kaauh-gray-light);
|
||||
color: var(--kaauh-teal-dark);
|
||||
}
|
||||
|
||||
/* --- First/Last Item Border Radius (Optional Rounding) --- */
|
||||
.pagination .page-item:first-child .page-link {
|
||||
border-top-left-radius: 0.5rem;
|
||||
border-bottom-left-radius: 0.5rem;
|
||||
}
|
||||
.pagination .page-item:last-child .page-link {
|
||||
border-top-right-radius: 0.5rem;
|
||||
border-bottom-right-radius: 0.5rem;
|
||||
}
|
||||
@ -1,61 +1,59 @@
|
||||
{% if page_obj.has_previous or page_obj.has_next %}
|
||||
|
||||
{% load url_extras i18n %}
|
||||
{% if page_obj.has_other_pages %}
|
||||
<nav aria-label="Page navigation" class="mt-4">
|
||||
<ul class="pagination justify-content-center">
|
||||
|
||||
{# Helper to build the query string while excluding the 'page' parameter #}
|
||||
{% load url_extras %}
|
||||
|
||||
{# Build a string of all current filters (e.g., &department=IT&type=FULL_TIME) #}
|
||||
{# Get the filter parameters (e.g., "q=searchterm&job=dev") #}
|
||||
{% add_get_params request.GET as filter_params %}
|
||||
{% with filter_params=filter_params %}
|
||||
|
||||
{# Define the & prefix logic inline to avoid custom tags #}
|
||||
{% if filter_params %}{% if "?" in request.get_full_path or "page" in request.get_full_path %}{% endif %}{% endif %}
|
||||
|
||||
{# --- First & Previous --- #}
|
||||
{% if page_obj.has_previous %}
|
||||
|
||||
{# First Page Link #}
|
||||
<li class="page-item">
|
||||
<a class="page-link text-primary-theme"
|
||||
href="?page=1{{ filter_params }}">
|
||||
First
|
||||
<a class="page-link text-primary-theme" href="?page=1{% if filter_params %}&{{ filter_params }}{% endif %}">
|
||||
<i class="fas fa-angle-double-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{# Previous Page Link #}
|
||||
<li class="page-item">
|
||||
<a class="page-link text-primary-theme"
|
||||
href="?page={{ page_obj.previous_page_number }}{{ filter_params }}">
|
||||
Previous
|
||||
<a class="page-link text-primary-theme" href="?page={{ page_obj.previous_page_number }}{% if filter_params %}&{{ filter_params }}{% endif %}">
|
||||
<i class="fas fa-angle-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{# Current Page Status - Use your teal/custom background class here #}
|
||||
<li class="page-item active" aria-current="page">
|
||||
<span class="page-link bg-kaauh-teal text-white">
|
||||
{{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
|
||||
</span>
|
||||
</li>
|
||||
{# --- Page Numbers --- #}
|
||||
{# --- Page Numbers --- #}
|
||||
{% for num in page_obj.paginator.page_range %}
|
||||
{% if page_obj.number == num %}
|
||||
<li class="page-item active"><span class="page-link bg-kaauh-teal text-white border-kaauh-teal">{{ num }}</span></li>
|
||||
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
|
||||
<li class="page-item"><a class="page-link text-primary-theme" href="?page={{ num }}{% if filter_params %}&{{ filter_params }}{% endif %}">{{ num }}</a></li>
|
||||
{% elif num == 1 or num == page_obj.paginator.num_pages %}
|
||||
{# Optional: Always show first and last page number #}
|
||||
<li class="page-item"><a class="page-link text-primary-theme" href="?page={{ num }}{% if filter_params %}&{{ filter_params }}{% endif %}">{{ num }}</a></li>
|
||||
{% elif num == page_obj.number|add:'-3' or num == page_obj.number|add:'3' %}
|
||||
{# Show the dots #}
|
||||
<li class="page-item disabled"><span class="page-link">...</span></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{# --- Next & Last --- #}
|
||||
{% if page_obj.has_next %}
|
||||
|
||||
{# Next Page Link #}
|
||||
<li class="page-item">
|
||||
<a class="page-link text-primary-theme"
|
||||
href="?page={{ page_obj.next_page_number }}{{ filter_params }}">
|
||||
Next
|
||||
<a class="page-link text-primary-theme" href="?page={{ page_obj.next_page_number }}{% if filter_params %}&{{ filter_params }}{% endif %}">
|
||||
<i class="fas fa-angle-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{# Last Page Link #}
|
||||
<li class="page-item">
|
||||
<a class="page-link text-primary-theme"
|
||||
href="?page={{ page_obj.paginator.num_pages }}{{ filter_params }}">
|
||||
Last
|
||||
<a class="page-link text-primary-theme" href="?page={{ page_obj.paginator.num_pages }}{% if filter_params %}&{{ filter_params }}{% endif %}">
|
||||
<i class="fas fa-angle-double-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% endwith %}
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
@ -138,19 +138,7 @@
|
||||
font-size: 0.8rem !important;
|
||||
}
|
||||
|
||||
/* Pagination Styling */
|
||||
.pagination .page-link {
|
||||
color: var(--kaauh-teal);
|
||||
border-color: var(--kaauh-border);
|
||||
}
|
||||
.pagination .page-item.active .page-link {
|
||||
background-color: var(--kaauh-teal);
|
||||
border-color: var(--kaauh-teal);
|
||||
}
|
||||
.pagination .page-link:hover {
|
||||
color: var(--kaauh-teal-dark);
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% load i18n %}
|
||||
{% block title %}{{ job.title }} - Applicants{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
@ -374,33 +374,31 @@
|
||||
|
||||
{% block content %}
|
||||
<div class="job-applicants-container">
|
||||
<!-- Job Header -->
|
||||
<div class="job-header">
|
||||
<h1>{{ job.title }}</h1>
|
||||
<p>{{ job.department|default:"General" }} • {{ job.get_job_type_display }} • {{ job.get_workplace_type_display }}</p>
|
||||
<div class="job-meta">
|
||||
<div class="job-meta-item">
|
||||
<span></span>
|
||||
<span>{{ total_applications }} Total Applicants</span>
|
||||
<i class="fas fa-users"></i>
|
||||
<span>{{ total_applications }} {% trans "Total Applicants" %}</span>
|
||||
</div>
|
||||
{% if job.max_applications %}
|
||||
<div class="job-meta-item">
|
||||
<span></span>
|
||||
<span>{{ job.max_applications }} Positions Available</span>
|
||||
<i class="fas fa-briefcase"></i>
|
||||
<span>{{ job.max_applications }} {% trans "Positions Available" %}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="job-meta-item">
|
||||
<span></span>
|
||||
<span>Posted {{ job.created_at|date:"M d, Y" }}</span>
|
||||
<i class="fas fa-calendar-alt"></i>
|
||||
<span>{% trans "Posted" %} {{ job.created_at|date:"M d, Y" }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistics Section -->
|
||||
<div class="stats-section">
|
||||
<div class="stat-card">
|
||||
<div class="stat-number">{{ total_applications }}</div>
|
||||
<div class="stat-label">Total Applications</div>
|
||||
<div class="stat-label">{% trans "Total Applications" %}</div>
|
||||
</div>
|
||||
|
||||
{% for stage_key, stage_data in stage_stats.items %}
|
||||
@ -413,32 +411,29 @@
|
||||
{% if ai_score_stats.average %}
|
||||
<div class="stat-card">
|
||||
<div class="stat-number">{{ ai_score_stats.average|floatformat:1 }}</div>
|
||||
<div class="stat-label">Average AI Score</div>
|
||||
<div class="stat-label">{% trans "Average AI Score" %}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Filters Section -->
|
||||
<div class="filters-section">
|
||||
<form method="GET" class="filters-form">
|
||||
<div class="filters-grid">
|
||||
<!-- Search Box -->
|
||||
<div class="filter-group">
|
||||
<label for="search"> Search Applicants</label>
|
||||
<label for="search">{% trans "Search Applicants" %}</label>
|
||||
<input
|
||||
type="text"
|
||||
id="search"
|
||||
name="q"
|
||||
value="{{ search_query }}"
|
||||
placeholder="Search by name, email, or phone..."
|
||||
placeholder="{% trans 'Search by name, email, or phone...' %}"
|
||||
>
|
||||
</div>
|
||||
|
||||
<!-- Stage Filter -->
|
||||
<div class="filter-group">
|
||||
<label for="stage"> Application Stage</label>
|
||||
<label for="stage">{% trans "Application Stage" %}</label>
|
||||
<select id="stage" name="stage">
|
||||
<option value="">All Stages</option>
|
||||
<option value="">{% trans "All Stages" %}</option>
|
||||
{% for key, value in stage_choices %}
|
||||
<option value="{{ key }}" {% if stage_filter == key %}selected{% endif %}>
|
||||
{{ value }}
|
||||
@ -447,9 +442,8 @@
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- AI Score Range -->
|
||||
<div class="filter-group">
|
||||
<label for="min_ai_score"> Min AI Score</label>
|
||||
<label for="min_ai_score">{% trans "Min AI Score" %}</label>
|
||||
<input
|
||||
type="number"
|
||||
id="min_ai_score"
|
||||
@ -462,7 +456,7 @@
|
||||
</div>
|
||||
|
||||
<div class="filter-group">
|
||||
<label for="max_ai_score"> Max AI Score</label>
|
||||
<label for="max_ai_score">{% trans "Max AI Score" %}</label>
|
||||
<input
|
||||
type="number"
|
||||
id="max_ai_score"
|
||||
@ -474,9 +468,8 @@
|
||||
>
|
||||
</div>
|
||||
|
||||
<!-- Date Range -->
|
||||
<div class="filter-group">
|
||||
<label for="date_from"> From Date</label>
|
||||
<label for="date_from">{% trans "From Date" %}</label>
|
||||
<input
|
||||
type="date"
|
||||
id="date_from"
|
||||
@ -486,7 +479,7 @@
|
||||
</div>
|
||||
|
||||
<div class="filter-group">
|
||||
<label for="date_to"> To Date</label>
|
||||
<label for="date_to">{% trans "To Date" %}</label>
|
||||
<input
|
||||
type="date"
|
||||
id="date_to"
|
||||
@ -495,37 +488,33 @@
|
||||
>
|
||||
</div>
|
||||
|
||||
<!-- Sort By -->
|
||||
<div class="filter-group">
|
||||
<label for="sort"> Sort By</label>
|
||||
<label for="sort">{% trans "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="person__first_name" {% if sort_by == 'person__first_name' %}selected{% endif %}>Name (A-Z)</option>
|
||||
<option value="-person__first_name" {% if sort_by == '-person__first_name' %}selected{% endif %}>Name (Z-A)</option>
|
||||
<option value="stage" {% if sort_by == 'stage' %}selected{% endif %}>Stage</option>
|
||||
<option value="-created_at" {% if sort_by == '-created_at' %}selected{% endif %}>{% trans "Newest First" %}</option>
|
||||
<option value="created_at" {% if sort_by == 'created_at' %}selected{% endif %}>{% trans "Oldest First" %}</option>
|
||||
<option value="person__first_name" {% if sort_by == 'person__first_name' %}selected{% endif %}>{% trans "Name (A-Z)" %}</option>
|
||||
<option value="-person__first_name" {% if sort_by == '-person__first_name' %}selected{% endif %}>{% trans "Name (Z-A)" %}</option>
|
||||
<option value="stage" {% if sort_by == 'stage' %}selected{% endif %}>{% trans "Stage" %}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filter Actions -->
|
||||
<div class="filters-actions">
|
||||
<button type="submit" class="btn-filter btn-primary">
|
||||
Apply Filters
|
||||
<i class="fas fa-filter"></i> {% trans "Apply Filters" %}
|
||||
</button>
|
||||
<a href="{% url 'job_applicants' job.slug %}" class="btn-filter btn-secondary">
|
||||
Clear All
|
||||
<i class="fas fa-undo"></i> {% trans "Clear All" %}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Applicants Grid -->
|
||||
{% if page_obj.object_list %}
|
||||
<div class="applicants-grid">
|
||||
{% for application in page_obj.object_list %}
|
||||
<div class="applicant-card">
|
||||
<!-- Applicant Header -->
|
||||
<div class="applicant-header">
|
||||
<div class="applicant-info">
|
||||
<div class="applicant-name">
|
||||
@ -541,15 +530,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Applicant Meta -->
|
||||
<div class="applicant-meta">
|
||||
<div class="meta-item">
|
||||
<span></span>
|
||||
<span>Applied {{ application.created_at|date:"M d, Y" }}</span>
|
||||
<i class="far fa-clock"></i>
|
||||
<span>{% trans "Applied" %} {{ application.created_at|date:"M d, Y" }}</span>
|
||||
</div>
|
||||
{% if application.ai_analysis_data.analysis_data_en.match_score %}
|
||||
<div class="meta-item">
|
||||
<span></span>
|
||||
<i class="fas fa-robot"></i>
|
||||
<span class="ai-score {% if application.ai_analysis_data.analysis_data_en.match_score >= 75 %}high{% elif application.ai_analysis_data.analysis_data_en.match_score >= 50 %}medium{% else %}low{% endif %}">
|
||||
{{ application.ai_analysis_data.analysis_data_en.match_score }}%
|
||||
</span>
|
||||
@ -557,64 +545,44 @@
|
||||
{% endif %}
|
||||
{% if application.person.gpa %}
|
||||
<div class="meta-item">
|
||||
<span></span>
|
||||
<span>GPA: {{ application.person.gpa|floatformat:2 }}</span>
|
||||
<i class="fas fa-graduation-cap"></i>
|
||||
<span>{% trans "GPA" %}: {{ application.person.gpa|floatformat:2 }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Applicant Actions -->
|
||||
<div class="applicant-actions">
|
||||
{% comment %} <a href="{% url 'person_detail' application.person.pk %}" class="btn-action btn-view-profile">
|
||||
👁️ Profile
|
||||
</a> {% endcomment %}
|
||||
<a href="{% url 'application_detail' application.slug %}" class="btn-filter btn-primary btn-sm">
|
||||
Application
|
||||
<i class="fas fa-file-alt"></i> {% trans "Application" %}
|
||||
</a>
|
||||
{% if application.stage == 'Interview' %}
|
||||
<a href="{% url 'interview_list' %}" class="btn-filter btn-primary btn-sm">
|
||||
Schedule
|
||||
<i class="fas fa-calendar-check"></i> {% trans "Schedule" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
<a href="{% url 'message_create' %}?job={{ job.pk }}&candidate={{ application.pk }}" class="btn-filter btn-primary btn-sm">
|
||||
✉️ Email
|
||||
<i class="fas fa-envelope"></i> {% trans "Email" %}
|
||||
</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>
|
||||
{% include "includes/paginator.html" %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<!-- No Results -->
|
||||
<div class="no-results">
|
||||
<h3>😔 No Applicants Found</h3>
|
||||
<h3>😔 {% trans "No Applicants Found" %}</h3>
|
||||
<p>
|
||||
{% if search_query or stage_filter or min_ai_score or max_ai_score or date_from or date_to %}
|
||||
We couldn't find any applicants matching your current filters. Try adjusting your search criteria or clearing some filters.
|
||||
{% trans "We couldn't find any applicants matching your current filters. Try adjusting your search criteria or clearing some filters." %}
|
||||
{% else %}
|
||||
There are currently no applicants for this job.
|
||||
{% trans "There are currently no applicants for this job." %}
|
||||
{% endif %}
|
||||
</p>
|
||||
<a href="{% url 'job_applicants' job.slug %}" class="btn-filter btn-primary">
|
||||
🔄 Clear Filters
|
||||
<i class="fas fa-sync-alt"></i> {% trans "Clear Filters" %}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}Job Bank - All Opportunities{% endblock %}
|
||||
|
||||
@ -303,36 +304,7 @@
|
||||
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;
|
||||
@ -387,8 +359,8 @@
|
||||
<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>
|
||||
<h1>🏦 {% trans "Job Bank" %}</h1>
|
||||
<p>{% trans "Explore all available opportunities across departments and find your perfect role" %}</p>
|
||||
</div>
|
||||
|
||||
<!-- Filters Section -->
|
||||
@ -397,21 +369,21 @@
|
||||
<div class="filters-grid">
|
||||
<!-- Search Box -->
|
||||
<div class="filter-group search-box">
|
||||
<label for="search">🔍 Search Jobs</label>
|
||||
<label for="search">🔍 {% trans "Search Jobs" %}</label>
|
||||
<input
|
||||
type="text"
|
||||
id="search"
|
||||
name="q"
|
||||
value="{{ search_query }}"
|
||||
placeholder="Search by title, department, or keywords..."
|
||||
placeholder="{% trans "Search by title, department, or keywords..." %}"
|
||||
>
|
||||
</div>
|
||||
|
||||
<!-- Department Filter -->
|
||||
<div class="filter-group">
|
||||
<label for="department">📁 Department</label>
|
||||
<label for="department">📁 {% trans "Department" %}</label>
|
||||
<select id="department" name="department">
|
||||
<option value="">All Departments</option>
|
||||
<option value="">{% trans "All Departments" %}</option>
|
||||
{% for dept in departments %}
|
||||
<option value="{{ dept }}" {% if department_filter == dept %}selected{% endif %}>
|
||||
{{ dept }}
|
||||
@ -422,9 +394,9 @@
|
||||
|
||||
<!-- Job Type Filter -->
|
||||
<div class="filter-group">
|
||||
<label for="job_type">💼 Job Type</label>
|
||||
<label for="job_type">💼 {% trans "Job Type" %}</label>
|
||||
<select id="job_type" name="job_type">
|
||||
<option value="">All Types</option>
|
||||
<option value="">{% trans "All Types" %}</option>
|
||||
{% for key, value in job_types.items %}
|
||||
<option value="{{ key }}" {% if job_type_filter == key %}selected{% endif %}>
|
||||
{{ value }}
|
||||
@ -435,9 +407,9 @@
|
||||
|
||||
<!-- Workplace Type Filter -->
|
||||
<div class="filter-group">
|
||||
<label for="workplace_type">🏢 Workplace Type</label>
|
||||
<label for="workplace_type">🏢 {% trans "Workplace Type" %}</label>
|
||||
<select id="workplace_type" name="workplace_type">
|
||||
<option value="">All Types</option>
|
||||
<option value="">{% trans "All Types" %}</option>
|
||||
{% for key, value in workplace_types.items %}
|
||||
<option value="{{ key }}" {% if workplace_type_filter == key %}selected{% endif %}>
|
||||
{{ value }}
|
||||
@ -448,9 +420,9 @@
|
||||
|
||||
<!-- Status Filter -->
|
||||
<div class="filter-group">
|
||||
<label for="status">📊 Status</label>
|
||||
<label for="status">📊 {% trans "Status" %}</label>
|
||||
<select id="status" name="status">
|
||||
<option value="">All Statuses</option>
|
||||
<option value="">{% trans "All Statuses" %}</option>
|
||||
{% for key, value in status_choices.items %}
|
||||
<option value="{{ key }}" {% if status_filter == key %}selected{% endif %}>
|
||||
{{ value }}
|
||||
@ -461,25 +433,25 @@
|
||||
|
||||
<!-- Date Filter -->
|
||||
<div class="filter-group">
|
||||
<label for="date_filter">📅 Posted Within</label>
|
||||
<label for="date_filter">📅 {% trans "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>
|
||||
<option value="">{% trans "Any Time" %}</option>
|
||||
<option value="week" {% if date_filter == 'week' %}selected{% endif %}>{% trans "Last Week" %}</option>
|
||||
<option value="month" {% if date_filter == 'month' %}selected{% endif %}>{% trans "Last Month" %}</option>
|
||||
<option value="quarter" {% if date_filter == 'quarter' %}selected{% endif %}>{% trans "Last 3 Months" %}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Sort By -->
|
||||
<div class="filter-group">
|
||||
<label for="sort">🔄 Sort By</label>
|
||||
<label for="sort">🔄 {% trans "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>
|
||||
<option value="-created_at" {% if sort_by == '-created_at' %}selected{% endif %}>{% trans "Newest First" %}</option>
|
||||
<option value="created_at" {% if sort_by == 'created_at' %}selected{% endif %}>{% trans "Oldest First" %}</option>
|
||||
<option value="title" {% if sort_by == 'title' %}selected{% endif %}>{% trans Title %} (A-Z)</option>
|
||||
<option value="-title" {% if sort_by == '-title' %}selected{% endif %}>{% trans "Title" %} (Z-A)</option>
|
||||
<option value="department" {% if sort_by == 'department' %}selected{% endif %}>{% trans "Department" %} (A-Z)</option>
|
||||
<option value="-department" {% if sort_by == '-department' %}selected{% endif %}>{% trans "Department" %} (Z-A)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -487,10 +459,10 @@
|
||||
<!-- Filter Actions -->
|
||||
<div class="filters-actions">
|
||||
<button type="submit" class="btn-filter btn-primary">
|
||||
🔍 Apply Filters
|
||||
🔍 {% trans "Apply Filters" %}
|
||||
</button>
|
||||
<a href="{% url 'job_bank' %}" class="btn-filter btn-secondary">
|
||||
🔄 Clear All
|
||||
🔄 {% trans "Clear All" %}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
@ -499,9 +471,9 @@
|
||||
<!-- Results Header -->
|
||||
<div class="results-header">
|
||||
<div class="results-count">
|
||||
📊 Found <strong>{{ total_jobs }}</strong> job{{ total_jobs|pluralize }}
|
||||
📊 {% trans "Found" %} <strong>{{ total_jobs }}</strong> {%trans "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
|
||||
{% trans "with filters applied" %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@ -535,7 +507,7 @@
|
||||
{% if job.max_applications %}
|
||||
<div class="meta-item">
|
||||
<span class="meta-icon">👥</span>
|
||||
<span>{{ job.max_applications }} positions</span>
|
||||
<span>{{ job.max_applications }} {% trans "positions" %}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@ -549,11 +521,11 @@
|
||||
<div class="job-actions">
|
||||
{% if job.status == 'ACTIVE' %}
|
||||
<a href="{% url 'job_applicants' job.slug %}" class="btn-apply">
|
||||
<EFBFBD> View Applicants
|
||||
{% trans "View Applicants" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
<a href="{% url 'job_detail' job.slug %}" class="btn-view">
|
||||
👁️ View Details
|
||||
{% trans "View Details" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -562,35 +534,21 @@
|
||||
|
||||
<!-- 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>
|
||||
{% include "includes/paginator.html" %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<!-- No Results -->
|
||||
<div class="no-results">
|
||||
<h3>😔 No Jobs Found</h3>
|
||||
<h3> {% trans "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.
|
||||
{% trans "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!
|
||||
{% trans "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
|
||||
{% trans "Clear Filters" %}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@ -182,39 +182,8 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% if page_obj.has_other_pages %}
|
||||
<nav aria-label="Message pagination">
|
||||
<ul class="pagination justify-content-center">
|
||||
{% if page_obj.has_previous %}
|
||||
<li class="page-item">
|
||||
<a class="page-link text-primary-theme" href="?page={{ page_obj.previous_page_number }}&status={{ status_filter }}&type={{ type_filter }}&q={{ search_query }}">
|
||||
<i class="fas fa-chevron-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% for num in page_obj.paginator.page_range %}
|
||||
{% if page_obj.number == num %}
|
||||
<li class="page-item active">
|
||||
<span class="page-link bg-primary-theme border-primary-theme">{{ num }}</span>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item">
|
||||
<a class="page-link text-primary-theme" href="?page={{ num }}&status={{ status_filter }}&type={{ type_filter }}&q={{ search_query }}">{{ num }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if page_obj.has_next %}
|
||||
<li class="page-item">
|
||||
<a class="page-link text-primary-theme" href="?page={{ page_obj.next_page_number }}&status={{ status_filter }}&type={{ type_filter }}&q={{ search_query }}">
|
||||
<i class="fas fa-chevron-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% include "includes/paginator.html" %}
|
||||
{% else %}
|
||||
<div class="text-center text-muted py-5">
|
||||
<i class="fas fa-inbox fa-3x mb-3 text-primary-theme"></i>
|
||||
|
||||
@ -108,19 +108,7 @@
|
||||
background-color: var(--kaauh-gray-light);
|
||||
}
|
||||
|
||||
/* Pagination Link Styling */
|
||||
.pagination .page-item .page-link {
|
||||
color: var(--kaauh-teal-dark);
|
||||
border-color: var(--kaauh-border);
|
||||
}
|
||||
.pagination .page-item.active .page-link {
|
||||
background-color: var(--kaauh-teal);
|
||||
border-color: var(--kaauh-teal);
|
||||
color: white;
|
||||
}
|
||||
.pagination .page-item:hover .page-link:not(.active) {
|
||||
background-color: #e9ecef;
|
||||
}
|
||||
|
||||
|
||||
/* Profile Image Styling */
|
||||
.profile-image-small {
|
||||
|
||||
@ -192,47 +192,7 @@
|
||||
|
||||
<!-- Pagination -->
|
||||
{% if page_obj.has_other_pages %}
|
||||
<nav aria-label="{% trans 'Assignments pagination' %}">
|
||||
<ul class="pagination justify-content-center mt-4">
|
||||
{% if page_obj.has_previous %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page=1{% if search_query %}&q={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}">
|
||||
<i class="fas fa-angle-double-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if search_query %}&q={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}">
|
||||
<i class="fas fa-angle-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% for num in page_obj.paginator.page_range %}
|
||||
{% if page_obj.number == num %}
|
||||
<li class="page-item active">
|
||||
<span class="page-link">{{ num }}</span>
|
||||
</li>
|
||||
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ num }}{% if search_query %}&q={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}">{{ num }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if page_obj.has_next %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ page_obj.next_page_number }}{% if search_query %}&q={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}">
|
||||
<i class="fas fa-angle-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}{% if search_query %}&q={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}">
|
||||
<i class="fas fa-angle-double-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
{% include "includes/paginator.html" %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="text-center py-5">
|
||||
|
||||
@ -219,6 +219,7 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% include "includes/paginator.html" %}
|
||||
{% else %}
|
||||
<div class="text-center py-5">
|
||||
<i class="fas fa-briefcase fa-3x text-muted mb-3"></i>
|
||||
|
||||
@ -120,19 +120,6 @@
|
||||
background-color: var(--kaauh-gray-light);
|
||||
}
|
||||
|
||||
/* Pagination Link Styling (Consistent) */
|
||||
.pagination .page-item .page-link {
|
||||
color: var(--kaauh-teal-dark);
|
||||
border-color: var(--kaauh-border);
|
||||
}
|
||||
.pagination .page-item.active .page-link {
|
||||
background-color: var(--kaauh-teal);
|
||||
border-color: var(--kaauh-teal);
|
||||
color: white;
|
||||
}
|
||||
.pagination .page-item:hover .page-link:not(.active) {
|
||||
background-color: #e9ecef;
|
||||
}
|
||||
|
||||
/* Filter & Search Layout Adjustments */
|
||||
.filter-buttons {
|
||||
|
||||
@ -40,14 +40,14 @@
|
||||
<div class="stat-caption">{% trans "Total Slots to be Filled " %}</div>
|
||||
</div>
|
||||
|
||||
{# GLOBAL - 5. Total Participants #}
|
||||
{% comment %} {# GLOBAL - 5. Total Participants #}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-address-book stat-icon"></i> {% trans "Total Participants" %}</h3>
|
||||
</div>
|
||||
<div class="stat-value">{{ total_participants }}</div>
|
||||
<div class="stat-caption">{% trans "Total Recruiters/Interviewers" %}</div>
|
||||
</div>
|
||||
</div> {% endcomment %}
|
||||
|
||||
{# GLOBAL - 6. Total LinkedIn Posts #}
|
||||
{% comment %} <div class="card">
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
{% block title %}{% trans "Sources" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="container-fluid">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
@ -74,6 +75,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for source in page_obj %}
|
||||
<tr>
|
||||
<td>
|
||||
@ -153,7 +155,7 @@
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
{% block customJS %}
|
||||
<script>
|
||||
// Auto-refresh after status toggle
|
||||
document.body.addEventListener('htmx:afterRequest', function(evt) {
|
||||
|
||||
@ -262,6 +262,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% include "includes/paginator.html" %}
|
||||
|
||||
{# NOTE: Add Pagination links here if the `staffs` object is a Paginator object #}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user