This commit is contained in:
Flatlogic Bot 2026-06-09 23:17:01 +00:00
parent ef6dd13037
commit af768b6ac1
4 changed files with 64 additions and 13 deletions

View File

@ -44,6 +44,9 @@
<div class="col-lg-1 d-grid">
<button class="btn btn-dark" type="submit">Go</button>
</div>
<div class="col-lg-12">
<a class="small text-decoration-none" href="{% url 'job_list' %}">Clear filters</a>
</div>
</div>
</form>
</div>
@ -59,6 +62,19 @@
</div>
{% endfor %}
</div>
{% if jobs.has_other_pages %}
<nav class="mt-4" aria-label="Jobs pagination">
<ul class="pagination">
{% if jobs.has_previous %}
<li class="page-item"><a class="page-link" href="?{% if current_filters_qs %}{{ current_filters_qs }}&{% endif %}page={{ jobs.previous_page_number }}">Previous</a></li>
{% endif %}
<li class="page-item disabled"><span class="page-link">Page {{ jobs.number }} of {{ jobs.paginator.num_pages }}</span></li>
{% if jobs.has_next %}
<li class="page-item"><a class="page-link" href="?{% if current_filters_qs %}{{ current_filters_qs }}&{% endif %}page={{ jobs.next_page_number }}">Next</a></li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="empty-state">
<div class="empty-orb"></div>

View File

@ -44,6 +44,9 @@
<div class="col-lg-1 d-grid">
<button class="btn btn-dark" type="submit">Go</button>
</div>
<div class="col-lg-12">
<a class="small text-decoration-none" href="{% url 'ops_dashboard' %}">Clear filters</a>
</div>
</div>
</form>
@ -81,6 +84,19 @@
</tbody>
</table>
</div>
{% if sources.has_other_pages %}
<nav class="mt-3" aria-label="Sources pagination">
<ul class="pagination mb-0">
{% if sources.has_previous %}
<li class="page-item"><a class="page-link" href="?{% if current_filters_qs %}{{ current_filters_qs }}&{% endif %}page={{ sources.previous_page_number }}">Previous</a></li>
{% endif %}
<li class="page-item disabled"><span class="page-link">Page {{ sources.number }} of {{ sources.paginator.num_pages }}</span></li>
{% if sources.has_next %}
<li class="page-item"><a class="page-link" href="?{% if current_filters_qs %}{{ current_filters_qs }}&{% endif %}page={{ sources.next_page_number }}">Next</a></li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="empty-state">No sources yet. Register the first portal, agency, or company careers page.</div>
{% endif %}

View File

@ -1,5 +1,6 @@
from django.contrib import messages
from django.db.models import Count, Q
from django.core.paginator import Paginator
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import timezone
@ -96,20 +97,28 @@ def job_list(request):
family = request.GET.get("family", "").strip()
source_status = request.GET.get("source_status", "").strip()
jobs = JobPosting.objects.select_related("source").filter(is_active=True)
jobs_qs = JobPosting.objects.select_related("source").filter(is_active=True)
if query:
jobs = jobs.filter(
jobs_qs = jobs_qs.filter(
Q(title__icontains=query)
| Q(company__icontains=query)
| Q(location__icontains=query)
| Q(description__icontains=query)
)
if contract:
jobs = jobs.filter(contract_type=contract)
jobs_qs = jobs_qs.filter(contract_type=contract)
if family:
jobs = jobs.filter(source__family=family)
jobs_qs = jobs_qs.filter(source__family=family)
if source_status:
jobs = jobs.filter(source__status=source_status)
jobs_qs = jobs_qs.filter(source__status=source_status)
paginator = Paginator(jobs_qs, 9)
page_number = request.GET.get("page")
jobs = paginator.get_page(page_number)
filters = request.GET.copy()
filters.pop("page", None)
current_filters_qs = filters.urlencode()
context = {
**_meta("Search Job Offers", "Search normalized job offers collected for Dijon and nearby opportunities."),
@ -121,7 +130,8 @@ def job_list(request):
"contract_choices": JobPosting.ContractType.choices,
"family_choices": JobSource.Family.choices,
"source_status_choices": JobSource.Status.choices,
"result_count": jobs.count(),
"result_count": jobs_qs.count(),
"current_filters_qs": current_filters_qs,
}
return render(request, "core/job_list.html", context)
@ -144,13 +154,21 @@ def ops_dashboard(request):
family = request.GET.get("family", "").strip()
status = request.GET.get("status", "").strip()
sources = JobSource.objects.annotate(job_total=Count("jobs")).order_by("family", "name")
sources_qs = JobSource.objects.annotate(job_total=Count("jobs")).order_by("family", "name")
if query:
sources = sources.filter(Q(name__icontains=query) | Q(owner__icontains=query) | Q(url__icontains=query))
sources_qs = sources_qs.filter(Q(name__icontains=query) | Q(owner__icontains=query) | Q(url__icontains=query))
if family:
sources = sources.filter(family=family)
sources_qs = sources_qs.filter(family=family)
if status:
sources = sources.filter(status=status)
sources_qs = sources_qs.filter(status=status)
paginator = Paginator(sources_qs, 8)
page_number = request.GET.get("page")
sources = paginator.get_page(page_number)
filters = request.GET.copy()
filters.pop("page", None)
current_filters_qs = filters.urlencode()
recent_jobs = (
JobPosting.objects.select_related("source")
@ -166,8 +184,8 @@ def ops_dashboard(request):
.annotate(total=Count("id"))
.order_by("status")
)
needs_attention = sources.filter(status=JobSource.Status.ERROR).count()
stale_sources = sources.filter(last_checked_at__isnull=True).count()
needs_attention = sources_qs.filter(status=JobSource.Status.ERROR).count()
stale_sources = sources_qs.filter(last_checked_at__isnull=True).count()
return render(
request,
"core/ops_dashboard.html",
@ -183,11 +201,12 @@ def ops_dashboard(request):
"needs_attention": needs_attention,
"stale_sources": stale_sources,
"active_jobs": JobPosting.objects.filter(is_active=True).count(),
"total_sources": sources.count(),
"total_sources": sources_qs.count(),
"query": query,
"family": family,
"status": status,
"family_choices": JobSource.Family.choices,
"status_choices": JobSource.Status.choices,
"current_filters_qs": current_filters_qs,
},
)