From 4dd52e78b1a34aa1b956fe9bd39cfe7ca61795ad Mon Sep 17 00:00:00 2001 From: Faheed Date: Wed, 24 Dec 2025 15:25:37 +0300 Subject: [PATCH] ats ui update --- recruitment/views.py | 94 +- static/css/main.css | 945 +++++------------- templates/base.html | 91 +- templates/interviews/interview_detail.html | 39 +- templates/portal_base.html | 167 ++-- .../application_resume_template.html | 5 +- 6 files changed, 419 insertions(+), 922 deletions(-) diff --git a/recruitment/views.py b/recruitment/views.py index 81c4a71..5951654 100644 --- a/recruitment/views.py +++ b/recruitment/views.py @@ -4816,73 +4816,59 @@ def interview_list(request): return render(request, "interviews/interview_list.html", context) -# from django_ratelimit.decorators import ratelimit -# @ratelimit(key='user_or_ip', rate='1/m', block=True) -from django.core.cache import cache + @login_required @staff_user_required def generate_ai_questions(request, slug): """Generate AI-powered interview questions for a scheduled interview""" - lock_key = f"ai_lock_{request.user.id}" - is_new_request = cache.add(lock_key, "locked", timeout=60) - if not is_new_request: - return JsonResponse({ - "error": "Request in progress. Please wait a moment." - }, status=429) from django_q.tasks import async_task schedule = get_object_or_404(ScheduledInterview, slug=slug) messages.info(request,_("Generating interview questions.")) - try: - + + if request.method == "POST": + # Queue the AI question generation task + + task_id = async_task( + "recruitment.tasks.generate_interview_questions", + schedule.id, + sync=False + ) - if request.method == "POST": - # Queue the AI question generation task - task_id = async_task( - "recruitment.tasks.generate_interview_questions", - schedule.id, - sync=False - ) - + # if request.headers.get("X-Requested-With") == "XMLHttpRequest": + # return JsonResponse({ + # "status": "success", + # "message": "AI question generation started in background", + # "task_id": task_id + # }) + # else: + # messages.success( + # request, + # "AI question generation started. Questions will appear shortly." + # ) + # return redirect("interview_detail", slug=slug) - # if request.headers.get("X-Requested-With") == "XMLHttpRequest": - # return JsonResponse({ - # "status": "success", - # "message": "AI question generation started in background", - # "task_id": task_id - # }) - # else: - # messages.success( - # request, - # "AI question generation started. Questions will appear shortly." - # ) - # return redirect("interview_detail", slug=slug) + # # For GET requests, return existing questions if any + # questions = schedule.ai_questions.all().order_by("created_at") - # # For GET requests, return existing questions if any - # questions = schedule.ai_questions.all().order_by("created_at") + # if request.headers.get("X-Requested-With") == "XMLHttpRequest": + # return JsonResponse({ + # "status": "success", + # "questions": [ + # { + # "id": q.id, + # "text": q.question_text, + # "type": q.question_type, + # "difficulty": q.difficulty_level, + # "category": q.category, + # "created_at": q.created_at.isoformat() + # } + # for q in questions + # ] + # }) - # if request.headers.get("X-Requested-With") == "XMLHttpRequest": - # return JsonResponse({ - # "status": "success", - # "questions": [ - # { - # "id": q.id, - # "text": q.question_text, - # "type": q.question_type, - # "difficulty": q.difficulty_level, - # "category": q.category, - # "created_at": q.created_at.isoformat() - # } - # for q in questions - # ] - # }) - - return redirect("interview_detail", slug=slug) - except Exception: - # If the task fails to enqueue, release the lock so they can try again - cache.delete(lock_key) - raise + return redirect("interview_detail", slug=slug) @login_required diff --git a/static/css/main.css b/static/css/main.css index accadf3..43c1fa6 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -1,33 +1,45 @@ -/* - * KAAT-S Theme Styles (V2.0 - Consolidated Global, Nav, and Components) - * This file contains all variables, global layout styles, navigation, and component-specific styles. +/* * KAAT-S Theme Styles (V3.0 - Integrated Enterprise Suite) + * Consolidated Global, Sidebar CRM, Nav, and Components */ /* ---------------------------------- */ -/* 1. UI Variables and Global Reset */ +/* 1. VARIABLES & RESET */ /* ---------------------------------- */ :root { + /* Brand Colors */ --kaauh-teal: #00636e; --kaauh-teal-dark: #004a53; --kaauh-light-bg: #f9fbfd; --kaauh-border: #eaeff3; --kaauh-primary-text: #343a40; + + /* Functional Colors */ --kaauh-success: #28a745; --kaauh-info: #17a2b8; --kaauh-danger: #dc3545; --kaauh-warning: #ffc107; - --kaauh-border: #eaeff3; + --kaauh-gray-light: #f8f9fa; + + /* Sidebar Dimensions */ + --sidebar-width: 260px; + --sidebar-collapsed-width: 70px; + --topbar-height: 64px; + --sidebar-bg: #00363a; + --sidebar-hover: rgba(255, 255, 255, 0.1); + --sidebar-active: #007c8a; } -/* Primary Color Overrides */ +/* ---------------------------------- */ +/* 2. GLOBAL UTILITIES */ +/* ---------------------------------- */ .text-success { color: var(--kaauh-success) !important; } .text-info { color: var(--kaauh-info) !important; } .text-danger { color: var(--kaauh-danger) !important; } .text-warning { color: var(--kaauh-warning) !important; } -.text-primary-theme { color: var(--kaauh-teal) !important; } +.text-primary-theme, .text-primary { color: var(--kaauh-teal) !important; } .bg-primary-theme { background-color: var(--kaauh-teal) !important; } +.text-kaauh-primary { color: var(--kaauh-primary-text); } -/* Global Layout Control */ .max-width-1600 { max-width: 1600px; margin-right: auto; @@ -36,118 +48,151 @@ padding-left: var(--bs-gutter-x, 0.75rem); } -/* Global Container Padding for main content */ -.container-fluid.py-4 { padding-top: 1.5rem !important; padding-bottom: 1.5rem !important; } - -/* Main content minimum height */ main.container-fluid { min-height: calc(100vh - 200px); padding: 1.5rem 0; } /* ---------------------------------- */ -/* 2. Navigation and Header */ +/* 3. CRM SIDEBAR & LAYOUT */ /* ---------------------------------- */ +.sidebar { + width: var(--sidebar-width); + height: 100vh; + position: fixed; + top: 0; + left: 0; + background-color: var(--sidebar-bg); + z-index: 1050; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + display: flex; + flex-direction: column; + box-shadow: 4px 0 10px rgba(0,0,0,0.1); + overflow-x: hidden; +} -/* Top Bar (Contact/Social) */ +.sidebar-brand { + padding: 1.25rem; + text-align: center; + border-bottom: 1px solid rgba(255, 255, 255, 0.08); +} + +.sidebar-nav { + padding: 1.25rem 0; + flex-grow: 1; + overflow-y: auto; +} + +/* Sidebar Links */ +.nav-link-custom { + display: flex; + align-items: center; + padding: 0.85rem 1.5rem; + color: rgba(255, 255, 255, 0.7); + text-decoration: none !important; + transition: all 0.2s ease; + margin-bottom: 0.25rem; + font-weight: 500; + font-size: 0.95rem; + border-left: 4px solid transparent; + white-space: nowrap; +} + +.nav-link-custom:hover { + color: #fff; + background-color: var(--sidebar-hover); +} + +.nav-link-custom.active { + color: #fff; + background-color: var(--sidebar-active); + border-left: 4px solid var(--kaauh-warning); +} + +.nav-link-custom i { + width: 28px; + font-size: 1.1rem; + opacity: 0.9; +} + +/* Main Content Wrapper */ +.main-wrapper { + margin-left: var(--sidebar-width); + min-height: 100vh; + display: flex; + flex-direction: column; + transition: all 0.3s ease; +} + +.content-header { + height: var(--topbar-height); + background: #ffffff; + border-bottom: 1px solid var(--kaauh-border); + display: flex; + align-items: center; + padding: 0 1.5rem; + position: sticky; + top: 0; + z-index: 1000; +} + +/* Sidebar Collapse Logic */ +.sidebar.collapsed { + width: var(--sidebar-collapsed-width); +} + +.sidebar.collapsed + .main-wrapper { + margin-left: var(--sidebar-collapsed-width); +} + +.sidebar.collapsed .nav-link-custom span, +.sidebar.collapsed .sidebar-brand .fw-bold, +.sidebar.collapsed .badge, +.sidebar.collapsed .brand-subtitle { + display: none !important; +} + +.sidebar.collapsed .nav-link-custom i { + margin: 0 !important; + font-size: 1.2rem; + width: 100%; + text-align: center; +} + +/* ---------------------------------- */ +/* 4. NAVIGATION COMPONENTS */ +/* ---------------------------------- */ .top-bar { background-color: white; border-bottom: 1px solid var(--kaauh-border); font-size: 0.825rem; padding: 0.4rem 0; } -.top-bar a { text-decoration: none; } -.top-bar .social-icons i { - color: var(--kaauh-teal); - transition: color 0.2s; -} -.top-bar .social-icons i:hover { - color: var(--kaauh-teal-dark); -} -.top-bar .contact-item { - display: flex; - align-items: center; - gap: 0.35rem; - padding: 0.25rem 0.5rem; -} -.top-bar .logo-container img { - height: 60px; - object-fit: contain; -} -@media (max-width: 767.98px) { - .top-bar { - display: none; - } -} -/* Navbar */ -.navbar-brand { - font-weight: 700; - letter-spacing: -0.5px; - font-size: 1.25rem; - display: flex; - align-items: center; - gap: 0.5rem; -} .navbar-dark { background-color: var(--kaauh-teal) !important; box-shadow: 0 2px 6px rgba(0,0,0,0.12); } -/* Ensure the inner container of the navbar stretches to allow max-width-1600 */ -.navbar-dark > .container { - max-width: 100%; -} + .nav-link { font-weight: 500; transition: all 0.2s ease; - padding: 0.5rem 0.75rem; } -.nav-link:hover, -.nav-link.active { + +.nav-link:hover, .nav-link.active { color: white !important; background: rgba(255,255,255,0.12) !important; border-radius: 4px; } -/* Dropdown */ .dropdown-menu { backdrop-filter: blur(4px); background-color: rgba(255, 255, 255, 0.98); border: 1px solid var(--kaauh-border); box-shadow: 0 6px 20px rgba(0,0,0,0.12); border-radius: 8px; - padding: 0.5rem 0; - min-width: 200px; - will-change: transform, opacity; - transition: transform 0.2s ease, opacity 0.2s ease; -} -.dropdown-item { - padding: 0.5rem 1.25rem; - transition: background-color 0.15s; -} -.dropdown-item:hover { - background-color: var(--kaauh-light-bg); - color: var(--kaauh-teal-dark); } -/* Language Toggle Button Style */ -.language-toggle-btn { - color: white !important; - background: none !important; - border: none !important; - display: flex; - align-items: center; - gap: 0.3rem; - padding: 0.5rem 0.75rem !important; - font-weight: 500; - transition: all 0.2s ease; -} -.language-toggle-btn:hover { - background: rgba(255,255,255,0.12) !important; - border-radius: 4px; -} - -/* Profile Avatar */ .profile-avatar { width: 36px; height: 36px; @@ -158,42 +203,28 @@ main.container-fluid { justify-content: center; color: white; font-weight: bold; - font-size: 0.85rem; - transition: transform 0.1s ease; -} -.navbar-nav .dropdown-toggle:hover .profile-avatar { - transform: scale(1.05); -} -.navbar-nav .dropdown-toggle.p-0:hover { - background: none !important; } - /* ---------------------------------- */ -/* 3. Component Styles (Cards & Forms)*/ +/* 5. CARDS, FORMS & TYPOGRAPHY */ /* ---------------------------------- */ -.kaauh-card { +.kaauh-card, .card { border: 1px solid var(--kaauh-border); border-radius: 0.75rem; box-shadow: 0 4px 12px rgba(0,0,0,0.06); background-color: white; + overflow: hidden; } -/* NEW: Filter Controls Container Style */ -.filter-controls { +.filter-controls, .tier-controls { border: 1px solid var(--kaauh-border); border-radius: 0.75rem; - box-shadow: 0 4px 12px rgba(0,0,0,0.06); background-color: white; - padding: 1.5rem; /* Consistent internal padding */ - margin-bottom: 1.5rem; /* Space below filter */ + padding: 1.5rem; + margin-bottom: 1.5rem; } -/* Typography & Headers */ -.page-header { - color: var(--kaauh-teal-dark); - font-weight: 700; -} +.page-header { color: var(--kaauh-teal-dark); font-weight: 700; } .section-header { color: var(--kaauh-primary-text); font-weight: 600; @@ -201,14 +232,7 @@ main.container-fluid { padding-bottom: 0.5rem; margin-bottom: 1rem; } -label { - font-weight: 500; - color: var(--kaauh-primary-text); - font-size: 0.9rem; - margin-bottom: 0.25rem; -} -/* Forms - Default Size */ .form-control, .form-select { border-radius: 0.5rem; border: 1px solid #ced4da; @@ -216,71 +240,13 @@ label { font-size: 0.9rem; } -/* Forms - Compact Size (for modals/tables) */ -.form-control-sm, -.form-select-sm, -.btn-sm { - padding: 0.25rem 0.5rem !important; /* Adjusted padding */ +.form-control-sm, .form-select-sm, .btn-sm { + padding: 0.25rem 0.5rem !important; font-size: 0.8rem !important; - line-height: 1.25 !important; /* Standard small line height */ - height: auto !important; } -.form-select-sm { - padding: 0.25rem 2rem 0.25rem 0.5rem !important; /* Increased right padding for arrow */ - font-size: 0.8rem !important; - line-height: 1.25 !important; - height: auto !important; /* Remove fixed height */ - border-radius: 0.5rem; - border: 1px solid #ced4da; -} - -/* Scrollable Multiple Select Fix */ -.form-group select[multiple] { - max-height: 450px; - overflow-y: auto; - min-height: 250px; - padding: 0; -} - -/* Break Times Section Styling (Schedule Interviews) */ -.break-time-form { - background-color: #f8f9fa; - padding: 0.75rem; - border-radius: 0.5rem; - border: 1px solid var(--kaauh-border); - align-items: flex-end; -} -.note-box { - background-color: #fff3cd; - border-left: 5px solid var(--kaauh-warning); - padding: 1rem; - border-radius: 0.25rem; - font-size: 0.9rem; - margin-bottom: 1rem; -} - -/* Tier Controls (Kept for consistency/future use) */ -.tier-controls { - background-color: var(--kaauh-border); - border-radius: 0.75rem; - padding: 1.25rem; - margin-bottom: 2rem; - border: 1px solid var(--kaauh-border); -} -.tier-controls .form-row { - display: flex; - align-items: end; - gap: 1rem; -} -.tier-controls .form-group { - flex: 1; - margin-bottom: 0; -} - - /* ---------------------------------- */ -/* 4. Button Styles (Component Themed)*/ +/* 6. BUTTONS */ /* ---------------------------------- */ .btn-main-action { background-color: var(--kaauh-teal); @@ -296,6 +262,15 @@ label { } .btn-main-action.btn-sm { font-weight: 600 !important; } + +.btn-outline-primary { + color: var(--kaauh-teal); + border-color: var(--kaauh-teal); +} +.btn-outline-primary:hover { + background-color: var(--kaauh-teal); + color: white; +} .btn-outline-secondary { color: var(--kaauh-teal-dark); border-color: var(--kaauh-teal); @@ -306,6 +281,7 @@ label { border-color: var(--kaauh-teal-dark); } + .btn-bulk-pass { background-color: var(--kaauh-success); border-color: var(--kaauh-success); @@ -345,566 +321,74 @@ label { } /* ---------------------------------- */ -/* 5. Table & Footer Styles */ +/* 7. TABLES & PAGINATION */ /* ---------------------------------- */ -.candidate-table { - table-layout: fixed; +.candidate-table, .job-table { width: 100%; border-collapse: separate; - border-spacing: 0; background-color: white; border-radius: 0.5rem; overflow: hidden; - box-shadow: 0 4px 12px rgba(0,0,0,0.06); -} -.candidate-table thead { - background-color: var(--kaauh-border); -} -.candidate-table th { - padding: 0.75rem; - font-weight: 600; - color: var(--kaauh-teal-dark); - border-bottom: 2px solid var(--kaauh-teal); - font-size: 0.9rem; - vertical-align: middle; -} -.candidate-table td { - padding: 0.75rem; - border-bottom: 1px solid var(--kaauh-border); - vertical-align: middle; - font-size: 0.9rem; -} -.candidate-table tbody tr:hover { - background-color: #f1f3f4; -} -.candidate-name { - font-weight: 600; - color: var(--kaauh-primary-text); -} -.candidate-details { - font-size: 0.8rem; - color: #6c757d; } -/* Job Table Specific Styles */ -.job-table-wrapper { - background: white; - border-radius: 10px; - overflow: hidden; - box-shadow: 0 4px 16px rgba(0,0,0,0.06); - margin-bottom: 2rem; +.candidate-table th { + background-color: var(--kaauh-border); + color: var(--kaauh-teal-dark); + font-weight: 600; + padding: 0.75rem; + border-bottom: 2px solid var(--kaauh-teal); } + .job-table thead th { background: var(--kaauh-teal); color: white; - font-weight: 600; padding: 1rem; - text-align: center; -} -.job-table td { - padding: 1rem; - vertical-align: middle; - text-align: center; -} -.job-table tr:hover td { - background-color: rgba(0, 99, 110, 0.03); } -/* Table Responsiveness */ -@media (max-width: 575.98px) { - .table-responsive { - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } - .job-table th, - .job-table td { - white-space: nowrap; - font-size: 0.875rem; - } +.pagination .page-link { + color: var(--kaauh-teal); + border-color: var(--kaauh-border); } -/* Bulk Action Bar (Interview Management) */ -.bulk-action-bar { - display: flex; - align-items: center; - gap: 0.5rem; - padding-bottom: 0.75rem; - margin-bottom: 1rem; - border-bottom: 1px solid var(--kaauh-border); -} -.action-group { - display: flex; - align-items: center; - gap: 0.5rem; -} - -/* Badges (Adapted for Interview Tiers/Status) */ -.ai-score-badge { /* Used as an all-purpose secondary badge */ - background-color: var(--kaauh-teal-dark) !important; +.pagination .page-item.active .page-link { + background-color: var(--kaauh-teal); + border-color: var(--kaauh-teal); color: white; - font-weight: 700; - padding: 0.4em 0.8em; - border-radius: 0.4rem; - font-size: 0.8rem; } -.tier-badge { /* Used for Tier labels */ + +/* ---------------------------------- */ +/* 8. BADGES & TIMELINE */ +/* ---------------------------------- */ +.tier-badge, .stage-badge, .status-badge { font-size: 0.75rem; - padding: 0.125rem 0.5rem; - border-radius: 0.5rem; + padding: 0.25rem 0.6rem; + border-radius: 0.4rem; font-weight: 600; - margin-left: 0.5rem; display: inline-block; } + .tier-1-badge { background-color: var(--kaauh-success); color: white; } -.tier-2-badge { background-color: var(--kaauh-warning); color: #856404; } -.tier-3-badge { background-color: #d1ecf1; color: #0c5460; } -.cd_interview{ color: #00636e; } - -/* NEW: Application Stage Badges */ -.stage-badge { - font-size: 0.8rem; - padding: 0.2em 0.6em; - border-radius: 0.4rem; - font-weight: 600; - display: inline-block; - margin-top: 0.25rem; -} -.stage-Application { background-color: #e9ecef; color: #495057; } -.stage-Screening { background-color: #d1ecf1; color: #0c5460; } -.stage-Exam { background-color: #cce5ff; color: #004085; } .stage-Interview { background-color: #fff3cd; color: #856404; } -.stage-Offer { background-color: #d4edda; color: #155724; } -/* NEW: Applicant Status Badges */ -.status-badge { - font-size: 0.8rem; - padding: 0.2em 0.6em; - border-radius: 0.4rem; - font-weight: 500; - display: inline-block; -} -.bg-candidate { background-color: var(--kaauh-teal-dark); color: white; } -.bg-applicant { background-color: #f8f9fa; color: #495057; border: 1px solid #ced4da; } - -/* Table Column Width Fixes */ -.candidate-table th:nth-child(1) { width: 40px; } -.candidate-table th:nth-child(4) { width: 15%; } -.candidate-table th:nth-child(5) { width: 80px; } -.candidate-table th:nth-child(6) { width: 180px; } - -/* Footer & Alerts */ -.footer { - background: var(--kaauh-light-bg); - padding: 1.5rem 0; - border-top: 1px solid var(--kaauh-border); - font-size: 0.9rem; - color: #555; -} -.alert { - border: none; - border-radius: 8px; - box-shadow: 0 2px 6px rgba(0,0,0,0.05); -} - -/* ---------------------------------- */ -/* 6. RTL Support */ -/* ---------------------------------- */ -html[dir="rtl"] { - text-align: right; - direction: rtl; -} -html[dir="rtl"] .navbar-brand { - flex-direction: row-reverse; -} -html[dir="rtl"] .dropdown-menu { - right: auto; - left: 0; -} -/* RTL Spacing adjustments */ -html[dir="rtl"] .me-3 { margin-right: 0 !important; margin-left: 1rem !important; } -html[dir="rtl"] .ms-3 { margin-left: 0 !important; margin-right: 1rem !important; } -html[dir="rtl"] .me-2 { margin-right: 0 !important; margin-left: 0.5rem !important; } -html[dir="rtl"] .ms-2 { margin-left: 0 !important; margin-right: 0.5rem !important; } -html[dir="rtl"] .ms-auto { margin-left: 0 !important; margin-right: auto !important; } -html[dir="rtl"] .me-auto { margin-right: 0 !important; margin-left: auto !important; } - - -/* ================================================= */ -/* 1. THEME VARIABLES AND GLOBAL STYLES */ -/* ================================================= */ -:root { - --kaauh-teal: #00636e; - --kaauh-teal-dark: #004a53; - --kaauh-border: #eaeff3; - --kaauh-primary-text: #343a40; -} - -/* Primary Color Overrides */ -.text-primary { color: var(--kaauh-teal) !important; } -.text-info { color: #17a2b8 !important; } -.text-success { color: #28a745 !important; } -.text-secondary { color: #6c757d !important; } -.text-kaauh-primary { color: var(--kaauh-primary-text); } /* Custom class for primary text color if needed */ - - -/* ---------------------------------- */ -/* 2. Button Styles */ -/* ---------------------------------- */ - -/* Main Action Button Style (Used for Download Resume) */ -.btn-main-action { - background-color: var(--kaauh-teal); - border-color: var(--kaauh-teal); - color: white; - font-weight: 600; - padding: 0.6rem 1.2rem; - transition: all 0.2s ease; - display: inline-flex; - align-items: center; - gap: 0.5rem; -} -.btn-main-action:hover { - background-color: var(--kaauh-teal-dark); - border-color: var(--kaauh-teal-dark); - transform: translateY(-1px); - box-shadow: 0 4px 8px rgba(0,0,0,0.15); -} - -/* Outlined Button Styles */ -.btn-outline-primary { - color: var(--kaauh-teal); - border-color: var(--kaauh-teal); -} -.btn-outline-primary:hover { - background-color: var(--kaauh-teal); - color: white; -} -.btn-outline-secondary { - color: var(--kaauh-teal-dark); - border-color: var(--kaauh-teal); -} -.btn-outline-secondary:hover { - background-color: var(--kaauh-teal-dark); - color: white; - border-color: var(--kaauh-teal-dark); -} - -/* ---------------------------------- */ -/* 3. Card/Modal Styles */ -/* ---------------------------------- */ - -/* Card enhancements */ -.kaauh-card, .card { - border: 1px solid var(--kaauh-border); - border-radius: 0.75rem; - overflow: hidden; - box-shadow: 0 4px 12px rgba(0,0,0,0.06); - background-color: white; -} - -/* Candidate Header Card (The teal header) */ -.candidate-header-card { - background: linear-gradient(135deg, var(--kaauh-teal), #004d57); - color: white; - border-radius: 0.75rem 0.75rem 0 0; - padding: 1.5rem; - box-shadow: 0 4px 10px rgba(0,0,0,0.15); -} -.candidate-header-card h1 { - font-weight: 700; - margin: 0; - font-size: 1.8rem; -} -.candidate-header-card .badge { - font-size: 0.9rem; - padding: 0.4em 0.8em; - border-radius: 0.4rem; - font-weight: 700; -} - -/* ---------------------------------- */ -/* 4. Tab Navigation Styles (Candidate Detail View) */ -/* ---------------------------------- */ - -/* Left Column Tabs (Main Content Tabs) */ -.main-tabs { - border-bottom: 1px solid var(--kaauh-border); - background-color: #f8f9fa; - padding: 0 1.25rem; -} -.main-tabs .nav-link { - border: none; - border-bottom: 3px solid transparent; - color: var(--kaauh-primary-text); - font-weight: 500; - padding: 0.75rem 1rem; - margin-right: 0.5rem; - transition: all 0.2s; -} -.main-tabs .nav-link:hover { - color: var(--kaauh-teal); -} -.main-tabs .nav-link.active { - color: var(--kaauh-teal-dark) !important; - background-color: white !important; - border-bottom: 3px solid var(--kaauh-teal); - font-weight: 600; -} - -/* Right Column Card (General styling for tab content if needed) */ -.right-column-card .tab-content { - padding: 1.5rem 1.25rem; - background-color: white; -} - -/* ---------------------------------- */ -/* 5. Vertical Timeline Styling */ -/* ---------------------------------- */ - -/* Highlight box for the current stage */ -.current-stage { - border: 1px solid var(--kaauh-border); - background-color: #f0f8ff; /* Light, subtle blue background */ -} -.current-stage .text-primary { - color: var(--kaauh-teal) !important; -} - -.timeline { - position: relative; - padding-left: 2rem; -} +.timeline { position: relative; padding-left: 2rem; } .timeline::before { - content: ''; - position: absolute; - top: 0; - bottom: 0; - left: 1.25rem; - width: 2px; - background-color: var(--kaauh-border); -} -.timeline-item { - position: relative; - margin-bottom: 2rem; - padding-left: 1.5rem; + content: ''; position: absolute; top: 0; bottom: 0; left: 1.25rem; + width: 2px; background-color: var(--kaauh-border); } + .timeline-icon { - position: absolute; - left: 0; - top: 0; - width: 32px; - height: 32px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-size: 0.8rem; - z-index: 10; - border: 4px solid white; -} -.timeline-item:last-child { - margin-bottom: 0; -} - -/* Custom Timeline Background Classes for Stages (Using Bootstrap color palette) */ -.timeline-bg-applied { background-color: var(--kaauh-teal) !important; } -.timeline-bg-exam { background-color: #17a2b8 !important; } -.timeline-bg-interview { background-color: #ffc107 !important; } -.timeline-bg-offer { background-color: #28a745 !important; } -.timeline-bg-rejected { background-color: #dc3545 !important; } -.loading { - background: linear-gradient(135deg, var(--kaauh-teal), #004d57); - color: white; - border-radius: 0.75rem 0.75rem 0 0; - padding: 1.5rem; - box-shadow: 0 4px 10px rgba(0,0,0,0.15); -} - - - /* Breadcrumb Styling */ - .breadcrumb { - background-color: transparent; - padding: 0; - margin-bottom: 1rem; - } - - .breadcrumb-item + .breadcrumb-item::before { - content: ">"; - 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
  • 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; - } - - - - /* ---------------------------------- */ -/* 7. CRM Sidebar Layout (V2025) */ -/* ---------------------------------- */ - -:root { - --sidebar-width: 260px; - --topbar-height: 64px; - --sidebar-bg: #00363a; - --sidebar-hover: rgba(255, 255, 255, 0.1); - --sidebar-active: #007c8a; /* kaauh-light-teal */ -} - -/* Sidebar Container */ -.sidebar { - width: var(--sidebar-width); - height: 100vh; - position: fixed; - top: 0; - left: 0; /* Default LTR */ - background-color: var(--sidebar-bg); - z-index: 1050; - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); - display: flex; - flex-direction: column; - box-shadow: 4px 0 10px rgba(0,0,0,0.1); -} - -.sidebar-brand { - padding: 1.25rem; - text-align: center; - border-bottom: 1px solid rgba(255, 255, 255, 0.08); -} - -.sidebar-nav { - padding: 1.25rem 0; - flex-grow: 1; - overflow-y: auto; -} - -/* CRM-style Nav Links */ -.nav-link-custom { - display: flex; - align-items: center; - padding: 0.85rem 1.5rem; - color: rgba(255, 255, 255, 0.7); - text-decoration: none !important; - transition: all 0.2s ease; - margin-bottom: 0.25rem; - font-weight: 500; - font-size: 0.95rem; - border-left: 4px solid transparent; -} - -.nav-link-custom:hover { - color: #fff; - background-color: var(--sidebar-hover); -} - -.nav-link-custom.active { - color: #fff; - background-color: var(--sidebar-active); - border-left: 4px solid var(--kaauh-warning); /* Highlight accent */ -} - -.nav-link-custom i { - width: 28px; - font-size: 1.1rem; - opacity: 0.9; -} - -/* Main Wrapper - Offsets content for sidebar */ -.main-wrapper { - margin-left: var(--sidebar-width); - min-height: 100vh; - display: flex; - flex-direction: column; - transition: all 0.3s ease; -} - -/* Top Horizontal Content Header */ -.content-header { - height: var(--topbar-height); - background: #ffffff; - border-bottom: 1px solid var(--kaauh-border); - display: flex; - align-items: center; - padding: 0 1.5rem; - position: sticky; - top: 0; - z-index: 1000; - box-shadow: 0 2px 4px rgba(0,0,0,0.02); -} - -.main-container { - padding: 1.5rem; - flex-grow: 1; + position: absolute; left: 0; top: 0; width: 32px; height: 32px; + border-radius: 50%; display: flex; align-items: center; justify-content: center; + color: white; border: 4px solid white; z-index: 10; } /* ---------------------------------- */ -/* 8. CRM Mobile Responsiveness */ -/* ---------------------------------- */ - -@media (max-width: 991.98px) { - .sidebar { - left: calc(-1 * var(--sidebar-width)); - } - - .sidebar.show { - left: 0; - } - - .main-wrapper { - margin-left: 0 !important; - margin-right: 0 !important; - } -} - -/* ---------------------------------- */ -/* 9. CRM RTL Adjustments */ +/* 9. RTL SUPPORT */ /* ---------------------------------- */ +html[dir="rtl"] { text-align: right; direction: rtl; } html[dir="rtl"] .sidebar { - left: auto; - right: 0; + left: auto; right: 0; box-shadow: -4px 0 10px rgba(0,0,0,0.1); } @@ -913,6 +397,10 @@ html[dir="rtl"] .main-wrapper { margin-right: var(--sidebar-width); } +html[dir="rtl"] .sidebar.collapsed + .main-wrapper { + margin-right: var(--sidebar-collapsed-width); +} + html[dir="rtl"] .nav-link-custom { border-left: none; border-right: 4px solid transparent; @@ -922,39 +410,54 @@ html[dir="rtl"] .nav-link-custom.active { border-right: 4px solid var(--kaauh-warning); } +/* ---------------------------------- */ +/* 10. RESPONSIVE */ +/* ---------------------------------- */ @media (max-width: 991.98px) { - html[dir="rtl"] .sidebar { - right: calc(-1 * var(--sidebar-width)); - left: auto; - } + .sidebar { left: calc(-1 * var(--sidebar-width)); } + html[dir="rtl"] .sidebar { right: calc(-1 * var(--sidebar-width)); left: auto; } - html[dir="rtl"] .sidebar.show { - right: 0; - } + .sidebar.show { left: 0; } + html[dir="rtl"] .sidebar.show { right: 0; } + + .main-wrapper { margin-left: 0 !important; margin-right: 0 !important; } } - -.sidebar .mt-auto { - background: rgba(0, 0, 0, 0.1); /* Slightly darker than sidebar bg */ +/* --- Logout Section Improvements --- */ +.sidebar .logout-section { + padding: 0.85rem 1.5rem; /* Match nav-link-custom padding */ + transition: all 0.3s ease; + border-top: 1px solid rgba(255, 255, 255, 0.08); } -.sidebar .mt-auto span { - opacity: 0.8; - transition: opacity 0.3s; +.sidebar.collapsed .logout-section { + padding: 0.85rem 0; + text-align: center; } -.sidebar .mt-auto:hover span { - opacity: 1; +.sidebar .logout-section button { + color: rgba(255, 255, 255, 0.7) !important; + width: 100%; + justify-content: flex-start; + transition: color 0.2s; } - - -.powered-by-footer { - letter-spacing: 0.5px; - opacity: 0.7; - transition: opacity 0.3s ease; +.sidebar .logout-section button:hover { + color: var(--kaauh-danger) !important; } -.powered-by-footer:hover { - opacity: 1; +/* Hide text and handle icon centering in collapsed mode */ +.sidebar.collapsed .logout-section span { + display: none !important; +} + +.sidebar.collapsed .logout-section i { + margin: 0 !important; + width: 100%; + font-size: 1.1rem; +} + +/* Ensure form doesn't add extra margins */ +.sidebar .logout-section form { + margin: 0; } \ No newline at end of file diff --git a/templates/base.html b/templates/base.html index b3c87de..f7324df 100644 --- a/templates/base.html +++ b/templates/base.html @@ -21,27 +21,29 @@ + + + - - {% block customCSS %}{% endblock %} + {% block customCSS %}{% endblock %}
    - +
    {% trans "KAAUH Applicant Tracking System" %}
    @@ -124,7 +129,6 @@ {% endif %} - {% if LANGUAGE_CODE == 'en' %}
    {% csrf_token %} @@ -150,13 +154,13 @@
    {% endif %} + {% if request.user.is_authenticated %} + {% endif %}
    -
    +
    {% if messages %} {% for message in messages %}
    - + + + {% block customJS %}{% endblock %} \ No newline at end of file diff --git a/templates/interviews/interview_detail.html b/templates/interviews/interview_detail.html index 0fc3317..b098c8c 100644 --- a/templates/interviews/interview_detail.html +++ b/templates/interviews/interview_detail.html @@ -518,20 +518,35 @@
    -
    -
    - {% trans "AI Generated Questions" %} -
    -
    -
    - {% csrf_token %} - -
    + +
    +
    diff --git a/templates/portal_base.html b/templates/portal_base.html index ee454c2..3561419 100644 --- a/templates/portal_base.html +++ b/templates/portal_base.html @@ -22,15 +22,17 @@ - + + + {% block customCSS %}{% endblock %}
    -
    -
    - - -
    - - {% if request.user.user_type == 'agency' %} - {% trans "Agency Portal" %} - {% else %} - {% trans "Applicant Portal" %} - {% endif %} - | - KAAUH - -
    -
    +
    +
    + + +
    + + {% if request.user.user_type == 'agency' %}{% trans "Agency Portal" %}{% else %}{% trans "Applicant Portal" %}{% endif %} + | + KAAUH + +
    +
    -
    - - - {% if request.user.get_unread_message_count > 0 %} - - {{ request.user.get_unread_message_count }} - - {% endif %} - +
    + + + {% if request.user.get_unread_message_count > 0 %} + + {{ request.user.get_unread_message_count }} + + {% endif %} + - {% if LANGUAGE_CODE == 'en' %} + {% if LANGUAGE_CODE == 'en' %}
    {% csrf_token %} @@ -129,35 +130,37 @@
    - {% endif %} + {% endif %} - - - -
    -
    -
    +
    + -
    +
    {% if messages %} {% for message in messages %}
    -
    -
    - © {% now "Y" %} KAAUH. {% trans "All rights reserved." %} -
    - Vision 2030 -
    +
    +
    + © {% now "Y" %} KAAUH. {% trans "All rights reserved." %}
    - - {% include 'includes/delete_modal.html' %} + {% block customJS %}{% endblock %} \ No newline at end of file diff --git a/templates/recruitment/application_resume_template.html b/templates/recruitment/application_resume_template.html index d4cc9c3..30fd03c 100644 --- a/templates/recruitment/application_resume_template.html +++ b/templates/recruitment/application_resume_template.html @@ -915,7 +915,7 @@ {% if LANGUAGE_CODE == 'ar' %} {% with data_source=application.resume_data_ar analysis_source=application.analysis_data_ar %} -
    +
    {% include 'recruitment/partials/ai_overview_breadcromb.html' %} @@ -1264,8 +1264,7 @@ {% else %} {% with data_source=application.resume_data_en analysis_source=application.analysis_data_en %} -
    - +
    {% include 'recruitment/partials/ai_overview_breadcromb.html' %}