From b7d0dc8257535418ecfdac6b16a5799a542d3e9a Mon Sep 17 00:00:00 2001 From: Faheed Date: Sun, 26 Oct 2025 18:27:09 +0300 Subject: [PATCH 1/2] dashboard and spinner --- .../__pycache__/models.cpython-312.pyc | Bin 60206 -> 60689 bytes .../views_frontend.cpython-312.pyc | Bin 24310 -> 24309 bytes recruitment/models.py | 15 ++++ recruitment/views_frontend.py | 8 +- templates/jobs/job_detail.html | 10 +++ templates/recruitment/candidate_detail.html | 69 +++++++++++++++++- templates/recruitment/candidate_list.html | 65 ++++++++++++++++- .../recruitment/candidate_screening_view.html | 54 ++++++++++++++ templates/recruitment/dashboard.html | 23 +++--- 9 files changed, 226 insertions(+), 18 deletions(-) diff --git a/recruitment/__pycache__/models.cpython-312.pyc b/recruitment/__pycache__/models.cpython-312.pyc index 1dc5ea38285f681b63463fff72d3e67b5b663b16..a8ac33d8df1f062e9d365f7f9ac28935112b7ba3 100644 GIT binary patch delta 4737 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 delta 4269 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 diff --git a/recruitment/__pycache__/views_frontend.cpython-312.pyc b/recruitment/__pycache__/views_frontend.cpython-312.pyc index 85f9dabd04e1fbc4cb84b45bf60062e2774f768d..9de137fed81c6176bd96e62fc586eba11fb5848e 100644 GIT binary patch delta 279 zcmeyim+|XfM&8rByj%=GaN6i!#`2B4x7?WuvM0ZE*Jrr}WNeo8_{_+7f3l#LnbcLF zqM~acA_+v?01-Dq#P!LEUdFn&fXrJwCHW+tp*v!3}Uf>2sRMGKAAfr1gJbA!je&N k^Q?$#jErwL7e=KpaeoJ?{sSTeCqIahWmMk$FXjg$0Hg(0$4V}1&VH#@%YThcyF?RmzmTR zAiwA;h)4nv*FnS$5OHmCf|s%GO(63YPf31BVorQ2O3@vV>@5&+8$_sph;ty~ z{^SE*)@=7c%m>Rk;ofC 0: + vacancy_fill_rate = no_of_positions_filled / total_positions + else: + vacancy_fill_rate = 0.0 + + return vacancy_fill_rate + class JobPostingImage(models.Model): @@ -632,6 +646,7 @@ class Candidate(Base): ).exists() return future_meetings or today_future_meetings + class TrainingMaterial(Base): diff --git a/recruitment/views_frontend.py b/recruitment/views_frontend.py index d204d97..2c06fc7 100644 --- a/recruitment/views_frontend.py +++ b/recruitment/views_frontend.py @@ -395,12 +395,12 @@ def dashboard_view(request): high_potential_ratio = round((high_potential_count / total_candidates) * 100, 1) if total_candidates > 0 else 0 jobs=models.JobPosting.objects.all().order_by('internal_job_id') - selected_job_id=request.GET.get('selected_job_id','') + selected_job_pk=request.GET.get('selected_job_pk','') candidate_stage=['APPLIED','EXAM','INTERVIEW','OFFER'] apply_count,exam_count,interview_count,offer_count=[0]*4 - if selected_job_id: - job=jobs.get(internal_job_id=selected_job_id) + if selected_job_pk: + job=jobs.get(pk=selected_job_pk) apply_count=job.screening_candidates_count exam_count=job.exam_candidates_count interview_count=job.interview_candidates_count @@ -430,7 +430,7 @@ def dashboard_view(request): 'high_potential_count': high_potential_count, 'high_potential_ratio': high_potential_ratio, 'scored_ratio': scored_ratio, - 'current_job_id':selected_job_id, + 'current_job_id':selected_job_pk, 'jobs':jobs, 'all_candidates_count':all_candidates_count, 'candidate_stage':json.dumps(candidate_stage), diff --git a/templates/jobs/job_detail.html b/templates/jobs/job_detail.html index 3d5139f..a55900d 100644 --- a/templates/jobs/job_detail.html +++ b/templates/jobs/job_detail.html @@ -474,6 +474,16 @@ + +
+
+
+ +
{{ job.vacancy_fill_rate|floatformat:2 }}
+ {% trans "Vacancy Fill Rate" %} +
+
+
diff --git a/templates/recruitment/candidate_detail.html b/templates/recruitment/candidate_detail.html index f5a405f..5c33e40 100644 --- a/templates/recruitment/candidate_detail.html +++ b/templates/recruitment/candidate_detail.html @@ -176,6 +176,59 @@ .timeline-bg-interview { background-color: #ffc107 !important; } .timeline-bg-offer { background-color: #28a745 !important; } .timeline-bg-rejected { background-color: #dc3545 !important; } + + + + +/* ------------------------------------------- */ +/* 1. Base Spinner Styling */ +/* ------------------------------------------- */ +.kaats-spinner { + animation: kaats-spinner-rotate 1.5s linear infinite; /* Faster rotation */ + width: 40px; /* Standard size */ + height: 40px; + display: inline-block; /* Useful for table cells */ + vertical-align: middle; +} + +.kaats-spinner .path { + stroke: var(--kaauh-teal, #00636e); /* Use Teal color, fallback to dark teal */ + stroke-linecap: round; + /* Optional: Add a lighter background circle for contrast */ + /* stroke-dashoffset will be reset by the dash animation */ +} + +/* Optional: Background circle for better contrast (similar to Bootstrap) */ +.kaats-spinner circle { + stroke: var(--kaauh-border, #e9ecef); /* Light gray background */ + fill: none; + stroke-width: 5; /* Keep stroke-width on both circles */ +} + +/* ------------------------------------------- */ +/* 2. Keyframe Animations */ +/* ------------------------------------------- */ +@keyframes kaats-spinner-rotate { + 100% { + transform: rotate(360deg); + } +} + +@keyframes kaats-spinner-dash { + 0% { + stroke-dasharray: 1, 150; + stroke-dashoffset: 0; + } + 50% { + stroke-dasharray: 90, 150; + stroke-dashoffset: -35; + } + 100% { + stroke-dasharray: 90, 150; + stroke-dashoffset: -124; + } +} + {% endblock %} @@ -572,8 +625,20 @@ - -{% include 'recruitment/candidate_resume_template.html' %} +{% if candidate.is_resume_parsed %} + {% include 'recruitment/candidate_resume_template.html' %} +{% else %} + +
+ + + + + AI Score Loading..... +
+
+{% endif %} {% if user.is_staff %} diff --git a/templates/recruitment/candidate_list.html b/templates/recruitment/candidate_list.html index 72867db..41c2be9 100644 --- a/templates/recruitment/candidate_list.html +++ b/templates/recruitment/candidate_list.html @@ -132,6 +132,57 @@ display: flex; gap: 0.5rem; } + + +/* ------------------------------------------- */ +/* 1. Base Spinner Styling */ +/* ------------------------------------------- */ +.kaats-spinner { + animation: kaats-spinner-rotate 1.5s linear infinite; /* Faster rotation */ + width: 40px; /* Standard size */ + height: 40px; + display: inline-block; /* Useful for table cells */ + vertical-align: middle; +} + +.kaats-spinner .path { + stroke: var(--kaauh-teal, #00636e); /* Use Teal color, fallback to dark teal */ + stroke-linecap: round; + /* Optional: Add a lighter background circle for contrast */ + /* stroke-dashoffset will be reset by the dash animation */ +} + +/* Optional: Background circle for better contrast (similar to Bootstrap) */ +.kaats-spinner circle { + stroke: var(--kaauh-border, #e9ecef); /* Light gray background */ + fill: none; + stroke-width: 5; /* Keep stroke-width on both circles */ +} + +/* ------------------------------------------- */ +/* 2. Keyframe Animations */ +/* ------------------------------------------- */ +@keyframes kaats-spinner-rotate { + 100% { + transform: rotate(360deg); + } +} + +@keyframes kaats-spinner-dash { + 0% { + stroke-dasharray: 1, 150; + stroke-dashoffset: 0; + } + 50% { + stroke-dasharray: 90, 150; + stroke-dashoffset: -35; + } + 100% { + stroke-dasharray: 90, 150; + stroke-dashoffset: -124; + } +} + {% endblock %} @@ -232,11 +283,23 @@ {{ candidate.phone }} {{ candidate.job.title }} + {% if candidate.is_resume_parsed %} {% if candidate.professional_category != 'Uncategorized' %} {{ candidate.professional_category }} - {% endif %} + {% endif %} + {% else %} + +
+ + + + +
+
+ {% endif %} diff --git a/templates/recruitment/candidate_screening_view.html b/templates/recruitment/candidate_screening_view.html index b7e33b8..b828b8c 100644 --- a/templates/recruitment/candidate_screening_view.html +++ b/templates/recruitment/candidate_screening_view.html @@ -163,7 +163,51 @@ } +.kaats-spinner { + animation: kaats-spinner-rotate 1.5s linear infinite; /* Faster rotation */ + width: 40px; /* Standard size */ + height: 40px; + display: inline-block; /* Useful for table cells */ + vertical-align: middle; +} +.kaats-spinner .path { + stroke: var(--kaauh-teal, #00636e); /* Use Teal color, fallback to dark teal */ + stroke-linecap: round; + /* Optional: Add a lighter background circle for contrast */ + /* stroke-dashoffset will be reset by the dash animation */ +} + +/* Optional: Background circle for better contrast (similar to Bootstrap) */ +.kaats-spinner circle { + stroke: var(--kaauh-border, #e9ecef); /* Light gray background */ + fill: none; + stroke-width: 5; /* Keep stroke-width on both circles */ +} + +/* ------------------------------------------- */ +/* 2. Keyframe Animations */ +/* ------------------------------------------- */ +@keyframes kaats-spinner-rotate { + 100% { + transform: rotate(360deg); + } +} + +@keyframes kaats-spinner-dash { + 0% { + stroke-dasharray: 1, 150; + stroke-dashoffset: 0; + } + 50% { + stroke-dasharray: 90, 150; + stroke-dashoffset: -35; + } + 100% { + stroke-dasharray: 90, 150; + stroke-dashoffset: -124; + } +} {% endblock %} {% block content %} @@ -351,11 +395,21 @@ + {% if candidate.is_resume_parsed %} {% if candidate.match_score %} {{ candidate.match_score|default:"0" }}% {% endif %} + {% else %} +
+ + + + +
+ {% endif %} {% if candidate.screening_stage_rating %} diff --git a/templates/recruitment/dashboard.html b/templates/recruitment/dashboard.html index d55c31b..c297668 100644 --- a/templates/recruitment/dashboard.html +++ b/templates/recruitment/dashboard.html @@ -123,7 +123,7 @@ {% block content %}
-

{% trans "Recruitment Intelligence" %} 🧠

+

{% trans "Recruitment Analytics" %}

{# -------------------------------------------------------------------------- #} {# STATS CARDS SECTION #} @@ -156,7 +156,7 @@
-

{% trans "Avg. Match Score" %}

+

{% trans "Avg. Match Score" %}

{{ avg_match_score|floatformat:1 }}
{% trans "Average AI Score (0-100)" %}
@@ -164,7 +164,7 @@
-

{% trans "High Potential" %}

+

{% trans "High Potential" %}

{{ high_potential_count }}
{% trans "Candidates with Score ≥ 75 ({{ high_potential_ratio }}%)" %}
@@ -172,7 +172,7 @@
-

{% trans "Scored Profiles" %}

+

{% trans "Scored Profiles" %}

{{ scored_ratio|floatformat:1 }}%
{% trans "Percent of profiles processed by AI" %}
@@ -210,13 +210,13 @@ {{my_job}} {# Job Filter Dropdown - Consistent with Card Header Layout #} -
+ - {% for job in jobs%} - {% endfor %} @@ -275,7 +275,7 @@ // Pass context data safely to JavaScript const jobTitles = JSON.parse('{{ job_titles|escapejs }}').slice(0, 5); // Take top 5 const jobAppCounts = JSON.parse('{{ job_app_counts|escapejs }}').slice(0, 5); // Take top 5 - + // BAR CHART configuration const ctxBar = document.getElementById('applicationsChart').getContext('2d'); new Chart(ctxBar, { @@ -285,7 +285,7 @@ datasets: [{ label: '{% trans "Applications" %}', data: jobAppCounts, - backgroundColor: 'var(--kaauh-teal)', + backgroundColor: '#00636e', borderColor: 'var(--kaauh-teal-dark)', borderWidth: 1, barThickness: 50 @@ -307,7 +307,7 @@ y: { beginAtZero: true, title: { display: true, text: '{% trans "Total Applications" %}' }, - ticks: { color: '#333333', precision: 0 }, + ticks: { color: '#2222', precision: 0 }, grid: { color: '#e0e0e0' } }, x: { @@ -318,6 +318,7 @@ } }); + // DONUT CHART configuration const ctxDonut = document.getElementById('candidate_donout_chart').getContext('2d'); @@ -330,7 +331,7 @@ label: '{% trans "Candidate Count" %}', data: JSON.parse('{{ candidates_count|safe }}'), backgroundColor: [ - 'var(--kaauh-teal)', // Applied (Primary) + '#00636e', // Applied (Primary) 'rgb(255, 159, 64)', // Exam (Orange) 'rgb(54, 162, 235)', // Interview (Blue) 'rgb(75, 192, 192)' // Offer (Green) -- 2.39.5 From 6447a895c034103cc07b58e45e0bdec7b86c0995 Mon Sep 17 00:00:00 2001 From: Faheed Date: Sun, 26 Oct 2025 18:50:52 +0300 Subject: [PATCH 2/2] small fix --- .../views_frontend.cpython-312.pyc | Bin 24309 -> 24309 bytes recruitment/views_frontend.py | 2 +- templates/jobs/job_detail.html | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/recruitment/__pycache__/views_frontend.cpython-312.pyc b/recruitment/__pycache__/views_frontend.cpython-312.pyc index 9de137fed81c6176bd96e62fc586eba11fb5848e..72a41e00ab1f5f8d86402f7456e11d00019ebf36 100644 GIT binary patch delta 24 ecmeymm+|XfM&8rByj%=G&}jcJWA#Sf7jXb{=m|Ig delta 24 ecmeymm+|XfM&8rByj%=GaN6i!#`2B4FX8}p1_^Nh diff --git a/recruitment/views_frontend.py b/recruitment/views_frontend.py index 2c06fc7..2055fde 100644 --- a/recruitment/views_frontend.py +++ b/recruitment/views_frontend.py @@ -240,7 +240,7 @@ def candidate_detail(request, slug): stage_form = None if request.user.is_staff: stage_form = forms.CandidateStageForm() - + # parsed = JSON(json.dumps(parsed), indent=2, highlight=True, skip_keys=False, ensure_ascii=False, check_circular=True, allow_nan=True, default=None, sort_keys=False) # parsed = json_to_markdown_table([parsed]) return render(request, 'recruitment/candidate_detail.html', { diff --git a/templates/jobs/job_detail.html b/templates/jobs/job_detail.html index a55900d..25b27f2 100644 --- a/templates/jobs/job_detail.html +++ b/templates/jobs/job_detail.html @@ -347,7 +347,7 @@ {% trans "Create New Form Template" %} {% else %} - + {% trans "View Form Template" %} {% endif %} -- 2.39.5