translation and pagination to the new page regarding the job bank #132
@ -23,7 +23,7 @@ urlpatterns = [
|
||||
path("ckeditor5/", include('django_ckeditor_5.urls')),
|
||||
|
||||
path('application/<slug:slug>/', views.application_submit_form, name='application_submit_form'),
|
||||
path('application/<slug:template_slug>/submit/', views.application_submit, name='application_submit'),
|
||||
path('application/<slug:slug>/submit/', views.application_submit, name='application_submit'),
|
||||
path('application/<slug:slug>/apply/', views.job_application_detail, name='job_application_detail'),
|
||||
path('application/<slug:slug>/signup/', views.application_signup, name='application_signup'),
|
||||
path('application/<slug:slug>/success/', views.application_success, name='application_success'),
|
||||
@ -31,7 +31,7 @@ urlpatterns = [
|
||||
|
||||
path('api/v1/templates/', views.list_form_templates, name='list_form_templates'),
|
||||
path('api/v1/templates/save/', views.save_form_template, name='save_form_template'),
|
||||
path('api/v1/templates/<slug:template_slug>/', views.load_form_template, name='load_form_template'),
|
||||
path('api/v1/templates/<slug:slug>/', views.load_form_template, name='load_form_template'),
|
||||
path('api/v1/templates/<slug:template_slug>/delete/', views.delete_form_template, name='delete_form_template'),
|
||||
|
||||
path('api/v1/sync/task/<str:task_id>/status/', views.sync_task_status, name='sync_task_status'),
|
||||
|
||||
@ -119,12 +119,12 @@ urlpatterns = [
|
||||
path("forms/template/<slug:slug>/submissions/", views.form_template_submissions_list, name="form_template_submissions_list"),
|
||||
path("forms/template/<int:template_id>/all-submissions/", views.form_template_all_submissions, name="form_template_all_submissions"),
|
||||
|
||||
# Application Forms (Public)
|
||||
path("application/signup/<slug:template_slug>/", views.application_signup, name="application_signup"),
|
||||
path("application/<slug:slug>/", views.application_submit_form, name="application_submit_form"),
|
||||
path("application/<slug:slug>/submit/", views.application_submit, name="application_submit"),
|
||||
path("application/<slug:slug>/apply/", views.job_application_detail, name="job_application_detail"),
|
||||
path("application/<slug:slug>/success/", views.application_success, name="application_success"),
|
||||
# # Application Forms (Public)
|
||||
# path("application/signup/<slug:template_slug>/", views.application_signup, name="application_signup"),
|
||||
# path("application/<slug:slug>/", views.application_submit_form, name="application_submit_form"),
|
||||
# path("application/<slug:slug>/submit/", views.application_submit, name="application_submit"),
|
||||
# path("application/<slug:slug>/apply/", views.job_application_detail, name="job_application_detail"),
|
||||
# path("application/<slug:slug>/success/", views.application_success, name="application_success"),
|
||||
|
||||
# ========================================================================
|
||||
# INTEGRATION & EXTERNAL SERVICES
|
||||
|
||||
@ -1142,10 +1142,11 @@ def save_form_template(request):
|
||||
# )
|
||||
|
||||
|
||||
def load_form_template(request, template_slug):
|
||||
def load_form_template(request, slug):
|
||||
"""Load an existing form template"""
|
||||
try:
|
||||
template = get_object_or_404(FormTemplate, slug=template_slug)
|
||||
job = get_object_or_404(JobPosting, slug=slug)
|
||||
template = job.form_template
|
||||
|
||||
# Get stages with fields
|
||||
stages = []
|
||||
@ -1308,9 +1309,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=template_slug)
|
||||
return redirect("application_signup", slug=slug)
|
||||
|
||||
if request.user.user_type == "candidate":
|
||||
person = request.user.person_profile
|
||||
@ -1343,7 +1344,7 @@ def application_submit_form(request, slug):
|
||||
return render(
|
||||
request,
|
||||
"applicant/application_submit_form.html",
|
||||
{"template_slug": job.form_template.slug, "job_id": job.internal_job_id},
|
||||
{"template_slug": job.form_template.slug,"job_slug": job.slug, "job_id": job.internal_job_id},
|
||||
)
|
||||
|
||||
|
||||
@ -1351,24 +1352,19 @@ def application_submit_form(request, slug):
|
||||
@require_POST
|
||||
@login_required
|
||||
@candidate_user_required
|
||||
def application_submit(request, template_slug):
|
||||
import re
|
||||
|
||||
def application_submit(request, slug):
|
||||
"""Handle form submission"""
|
||||
if not request.user.is_authenticated or request.user.user_type != "candidate":
|
||||
return JsonResponse({"success": False, "message": "Unauthorized access."})
|
||||
# if not request.user.is_authenticated or request.user.user_type != "candidate":
|
||||
# return JsonResponse({"success": False, "message": "Unauthorized access."})
|
||||
|
||||
template = get_object_or_404(FormTemplate, slug=template_slug)
|
||||
job = template.job
|
||||
job = get_object_or_404(JobPosting, slug=slug)
|
||||
template = job.form_template
|
||||
|
||||
if request.method == "POST":
|
||||
try:
|
||||
with transaction.atomic():
|
||||
job_posting = JobPosting.objects.select_for_update().get(
|
||||
form_template=template
|
||||
)
|
||||
|
||||
current_count = job_posting.applications.count()
|
||||
if current_count >= job_posting.max_applications:
|
||||
with transaction.atomic():
|
||||
current_count = job.applications.count()
|
||||
if current_count >= job.max_applications:
|
||||
template.is_active = False
|
||||
template.save()
|
||||
return JsonResponse(
|
||||
@ -4700,8 +4696,7 @@ def source_toggle_status(request, slug):
|
||||
def application_signup(request, slug):
|
||||
from .forms import ApplicantSignupForm
|
||||
|
||||
form_template = get_object_or_404(FormTemplate, slug=slug)
|
||||
job = form_template.job
|
||||
job = get_object_or_404(JobPosting, slug=slug)
|
||||
|
||||
if request.method == "POST":
|
||||
form = ApplicantSignupForm(request.POST)
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
{% load account %}
|
||||
{% load crispy_forms_tags %}
|
||||
|
||||
{% block title %}{% translate "Email Addresses" %}{% endblock %}
|
||||
{% block title %}{% trans "Email Addresses" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container my-5">
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>KAAUH ATS - Sign In (Bootstrap)</title>
|
||||
<title>{% trans "KAAUH ATS - Sign In" %} </title>
|
||||
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
|
||||
|
||||
@ -2,15 +2,15 @@
|
||||
{% load i18n %}
|
||||
{% load account %}
|
||||
|
||||
{% block title %}{% translate "Sign Out" %}{% endblock %}
|
||||
{% block title %}{% trans "Sign Out" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container my-5">
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<h3 class="fw-bold">{% translate "Account Settings" %}</h3>
|
||||
<p class="text-muted">{% translate "Manage your personal details and security." %}</p>
|
||||
<h3 class="fw-bold">{% trans "Account Settings" %}</h3>
|
||||
<p class="text-muted">{% trans "Manage your personal details and security." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -23,18 +23,18 @@
|
||||
<div class="list-group list-group-flush rounded-4">
|
||||
{# Assuming a main 'Profile' or 'Personal Information' page exists #}
|
||||
<a href="{% url 'user_detail' user.pk %}" class="list-group-item list-group-item-action border-0 rounded-top-4 py-3">
|
||||
<i class="fas fa-user-circle me-2"></i> {% translate "Personal Information" %}
|
||||
<i class="fas fa-user-circle me-2"></i> {% trans "Personal Information" %}
|
||||
</a>
|
||||
<a href="{% url 'account_email' %}" class="list-group-item list-group-item-action border-0 py-3">
|
||||
<i class="fas fa-envelope me-2"></i> {% translate "Email Addresses" %}
|
||||
<i class="fas fa-envelope me-2"></i> {% trans "Email Addresses" %}
|
||||
</a>
|
||||
<a href="{% url 'account_change_password' %}" class="list-group-item list-group-item-action border-0 py-3">
|
||||
<i class="fas fa-lock me-2"></i> {% translate "Change Password" %}
|
||||
<i class="fas fa-lock me-2"></i> {% trans "Change Password" %}
|
||||
</a>
|
||||
|
||||
{# Highlight the current page (Sign Out) as active #}
|
||||
<a href="{% url 'account_logout' %}" class="list-group-item list-group-item-action active border-0 rounded-bottom-4 py-3" style="background-color: #fce8e8; color: #dc3545; font-weight: 500;" aria-current="true">
|
||||
<i class="fas fa-sign-out-alt me-2"></i> {% translate "Sign Out" %}
|
||||
<i class="fas fa-sign-out-alt me-2"></i> {% trans "Sign Out" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -47,9 +47,9 @@
|
||||
<div class="card-body p-4 text-center">
|
||||
|
||||
<i class="fas fa-sign-out-alt text-danger mb-4" style="font-size: 3rem;"></i>
|
||||
<h4 class="fw-bold mb-3">{% translate "Confirm Sign Out" %}</h4>
|
||||
<h4 class="fw-bold mb-3">{% trans "Confirm Sign Out" %}</h4>
|
||||
|
||||
<p class="lead mb-4">{% translate "Are you sure you want to sign out of your account?" %}</p>
|
||||
<p class="lead mb-4">{% trans "Are you sure you want to sign out of your account?" %}</p>
|
||||
|
||||
<form method="post" action="{% url 'account_logout' %}">
|
||||
{% csrf_token %}
|
||||
@ -63,12 +63,12 @@
|
||||
<div class="d-flex justify-content-center gap-3 mt-4">
|
||||
{# Sign Out button in danger color #}
|
||||
<button class="btn btn-danger btn-lg px-5" type="submit">
|
||||
{% translate "Sign Out" %}
|
||||
{% trans "Sign Out" %}
|
||||
</button>
|
||||
|
||||
{# Cancel/Go Back button with outline #}
|
||||
<a class="btn btn-outline-secondary btn-lg px-5" href="{% url 'account_email' %}">
|
||||
{% translate "Cancel" %}
|
||||
{% trans "Cancel" %}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>KAAUH ATS - Sign In (Bootstrap)</title>
|
||||
<title>{% trans Reset Password %}-KAAUH ATS</title>
|
||||
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>KAAUH ATS - Verify Email</title>
|
||||
<title>{% trans "Verify Email" %}-KAAUH ATS </title>
|
||||
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
{% extends 'applicant/partials/candidate_facing_base.html'%}
|
||||
|
||||
{% load static i18n %}
|
||||
{% block content %}
|
||||
<style>
|
||||
@ -542,6 +543,7 @@
|
||||
|
||||
const state = {
|
||||
templateId: '{{ template_slug }}',
|
||||
job_slug: '{{ job_slug }}',
|
||||
stages: [],
|
||||
currentStage: 0,
|
||||
formData: {},
|
||||
@ -765,7 +767,7 @@
|
||||
// API Functions
|
||||
async function loadFormTemplate() {
|
||||
try {
|
||||
const response = await fetch(`/api/v1/templates/${state.templateId}/`);
|
||||
const response = await fetch(`/api/v1/templates/${state.job_slug}/`);
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
@ -831,7 +833,7 @@
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await fetch(`/application/${state.templateId}/submit/`, {
|
||||
const response = await fetch(`/application/${state.job_slug}/submit/`, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
// IMPORTANT: Do NOT set Content-Type header when using FormData
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{% extends 'applicant/partials/candidate_facing_base.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Application" %}-{{ job.title }}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{# ------------------------------------------------ #}
|
||||
|
||||
@ -9,6 +9,11 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% trans "Careers" %} - {% block title %}{% trans "Application Form" %}{% endblock %}</title>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'image/favicon/apple-touch-icon.png'%}">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{% static 'image/favicon/favicon-32x32.png'%}">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'image/favicon/favicon-16x16.png'%}">
|
||||
<link rel="manifest" href="{% static 'image/favicon/site.webmanifest'%}">
|
||||
|
||||
|
||||
{% comment %} Load the correct Bootstrap CSS file for RTL/LTR {% endcomment %}
|
||||
{% if LANGUAGE_CODE == 'ar' %}
|
||||
|
||||
@ -7,7 +7,14 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="{% trans 'King Abdullah Academic University Hospital - Applicant Tracking System' %}">
|
||||
|
||||
<title>{% block title %}{% trans 'University ATS' %}{% endblock %}</title>
|
||||
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'image/favicon/apple-touch-icon.png'%}">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{% static 'image/favicon/favicon-32x32.png'%}">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'image/favicon/favicon-16x16.png'%}">
|
||||
<link rel="manifest" href="{% static 'image/favicon/site.webmanifest'%}">
|
||||
|
||||
{% comment %} Load correct Bootstrap CSS file for RTL/LTR {% endcomment %}
|
||||
{% if LANGUAGE_CODE == 'ar' %}
|
||||
@ -226,6 +233,9 @@
|
||||
<a class="dropdown-item py-2 px-4 d-flex align-items-center text-decoration-none text-teal" href="{% url 'user_detail' request.user.pk %}">
|
||||
<i class="fas fa-user-circle me-3 fs-5"></i> <span>{% trans "My Profile" %}</span>
|
||||
</a>
|
||||
<a class="dropdown-item py-2 px-4 d-flex align-items-center text-decoration-none text-teal" href="{% url 'job_bank' %}">
|
||||
<i class="fas fa-bank me-3 fs-5"></i> <span>{% trans "Job Bank" %}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% if request.user.is_superuser %}
|
||||
<li>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>ATS Form Builder - Vanilla JS</title>
|
||||
<title>{% trans "ATS Form Builder" %}</title>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
{% load form_filters %}
|
||||
|
||||
{% block title %}{{ form.name }} - Submission Details{% endblock %}
|
||||
{% block title %}{{ form.name }} - {% trans "Submission Details" %}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -1,428 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ form.title }} - Submissions{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h1><i class="fas fa-list"></i> Form Submissions</h1>
|
||||
<p class="text-muted mb-0">{{ form.title }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<a href="{% url 'form_preview' form.id %}" class="btn btn-outline-primary me-2" target="_blank">
|
||||
<i class="fas fa-eye"></i> Preview Form
|
||||
</a>
|
||||
<a href="{% url 'form_list' %}" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Back to Forms
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistics Cards -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-3">
|
||||
<div class="card bg-primary text-white">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<h4 class="mb-0">{{ page_obj.paginator.count }}</h4>
|
||||
<small>Total Submissions</small>
|
||||
</div>
|
||||
<div class="align-self-center">
|
||||
<i class="fas fa-users fa-2x opacity-75"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card bg-success text-white">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<h4 class="mb-0">{{ form.submissions.all|length }}</h4>
|
||||
<small>All Time</small>
|
||||
</div>
|
||||
<div class="align-self-center">
|
||||
<i class="fas fa-chart-line fa-2x opacity-75"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card bg-info text-white">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<h4 class="mb-0">
|
||||
{% if form.submissions.first %}
|
||||
{{ form.submissions.first.submitted_at|timesince }}
|
||||
{% else %}
|
||||
No submissions
|
||||
{% endif %}
|
||||
</h4>
|
||||
<small>Latest</small>
|
||||
</div>
|
||||
<div class="align-self-center">
|
||||
<i class="fas fa-clock fa-2x opacity-75"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card bg-warning text-white">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<h4 class="mb-0">{{ form.created_at|date:"M d" }}</h4>
|
||||
<small>Form Created</small>
|
||||
</div>
|
||||
<div class="align-self-center">
|
||||
<i class="fas fa-calendar fa-2x opacity-75"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Export Options -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0"><i class="fas fa-download"></i> Export Options</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<button class="btn btn-outline-primary me-2" onclick="exportSubmissions('csv')">
|
||||
<i class="fas fa-file-csv"></i> Export as CSV
|
||||
</button>
|
||||
<button class="btn btn-outline-success me-2" onclick="exportSubmissions('excel')">
|
||||
<i class="fas fa-file-excel"></i> Export as Excel
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary" onclick="exportSubmissions('json')">
|
||||
<i class="fas fa-file-code"></i> Export as JSON
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-md-6 text-end">
|
||||
<small class="text-muted">
|
||||
Download all submission data for analysis
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Submissions List -->
|
||||
{% if page_obj %}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">Recent Submissions</h5>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Submitted</th>
|
||||
<th>IP Address</th>
|
||||
<th>User Agent</th>
|
||||
<th>Data Fields</th>
|
||||
<th>Files</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for submission in page_obj %}
|
||||
<tr>
|
||||
<td>
|
||||
<span class="badge bg-primary">{{ submission.id }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<div>
|
||||
<strong>{{ submission.submitted_at|date:"M d, Y" }}</strong><br>
|
||||
<small class="text-muted">{{ submission.submitted_at|time:"g:i A" }}</small>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<code class="text-muted">{{ submission.ip_address|default:"N/A" }}</code>
|
||||
</td>
|
||||
<td>
|
||||
<small class="text-muted" title="{{ submission.user_agent }}">
|
||||
{% if submission.user_agent %}
|
||||
{{ submission.user_agent|truncatechars:50 }}
|
||||
{% else %}
|
||||
N/A
|
||||
{% endif %}
|
||||
</small>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-info">{{ submission.submission_data.keys|length }} fields</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-success">{{ submission.files.count }} files</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button type="button" class="btn btn-outline-primary" onclick="viewSubmission({{ submission.id }})" title="View Details">
|
||||
<i class="fas fa-eye"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-info" onclick="downloadSubmission({{ submission.id }})" title="Download">
|
||||
<i class="fas fa-download"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-danger" onclick="deleteSubmission({{ submission.id }})" title="Delete">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
{% if page_obj.has_other_pages %}
|
||||
<nav aria-label="Submissions pagination" class="mt-4">
|
||||
<ul class="pagination justify-content-center">
|
||||
{% if page_obj.has_previous %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page=1">First</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ page_obj.previous_page_number }}">Previous</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
<li class="page-item active">
|
||||
<span class="page-link">{{ page_obj.number }} of {{ page_obj.paginator.num_pages }}</span>
|
||||
</li>
|
||||
|
||||
{% if page_obj.has_next %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ page_obj.next_page_number }}">Next</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}">Last</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="card">
|
||||
<div class="card-body text-center py-5">
|
||||
<i class="fas fa-inbox fa-3x text-muted mb-3"></i>
|
||||
<h4>No submissions yet</h4>
|
||||
<p class="text-muted">This form hasn't received any submissions yet.</p>
|
||||
<a href="{% url 'form_preview' form.id %}" class="btn btn-primary" target="_blank">
|
||||
<i class="fas fa-external-link-alt"></i> Test Form
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Submission Detail Modal -->
|
||||
<div class="modal fade" id="submissionModal" tabindex="-1" aria-labelledby="submissionModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="submissionModalLabel">
|
||||
<i class="fas fa-file-alt"></i> Submission Details
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div id="submissionDetails">
|
||||
<!-- Submission details will be loaded here -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary" id="downloadSubmissionBtn">
|
||||
<i class="fas fa-download"></i> Download
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
let currentSubmissionId = null;
|
||||
|
||||
function viewSubmission(submissionId) {
|
||||
currentSubmissionId = submissionId;
|
||||
|
||||
fetch(`/recruitment/api/submissions/${submissionId}/`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
displaySubmissionDetails(data.submission);
|
||||
const modal = new bootstrap.Modal(document.getElementById('submissionModal'));
|
||||
modal.show();
|
||||
} else {
|
||||
alert('Error loading submission: ' + data.error);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('Error loading submission details');
|
||||
});
|
||||
}
|
||||
|
||||
function displaySubmissionDetails(submission) {
|
||||
const detailsHtml = `
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h6>Submission Information</h6>
|
||||
<table class="table table-sm">
|
||||
<tr>
|
||||
<td><strong>ID:</strong></td>
|
||||
<td>${submission.id}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Submitted:</strong></td>
|
||||
<td>${new Date(submission.submitted_at).toLocaleString()}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>IP Address:</strong></td>
|
||||
<td>${submission.ip_address || 'N/A'}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h6>Technical Details</h6>
|
||||
<table class="table table-sm">
|
||||
<tr>
|
||||
<td><strong>User Agent:</strong></td>
|
||||
<td><small>${submission.user_agent || 'N/A'}</small></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Files:</strong></td>
|
||||
<td>${submission.files ? submission.files.length : 0}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Data Fields:</strong></td>
|
||||
<td>${Object.keys(submission.submission_data).length}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<h6>Submitted Data</h6>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${Object.entries(submission.submission_data).map(([key, value]) => `
|
||||
<tr>
|
||||
<td><strong>${key}:</strong></td>
|
||||
<td>${formatFieldValue(value)}</td>
|
||||
</tr>
|
||||
`).join('')}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
${submission.files && submission.files.length > 0 ? `
|
||||
<hr>
|
||||
<h6>Uploaded Files</h6>
|
||||
<div class="list-group">
|
||||
${submission.files.map(file => `
|
||||
<div class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<i class="fas fa-file me-2"></i>
|
||||
<strong>${file.original_filename}</strong>
|
||||
<br>
|
||||
<small class="text-muted">
|
||||
${file.file_size ? formatFileSize(file.file_size) : 'Unknown size'} •
|
||||
Uploaded ${new Date(file.uploaded_at).toLocaleString()}
|
||||
</small>
|
||||
</div>
|
||||
<a href="${file.file_url}" class="btn btn-sm btn-outline-primary" target="_blank">
|
||||
<i class="fas fa-download"></i> Download
|
||||
</a>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
` : ''}
|
||||
`;
|
||||
|
||||
document.getElementById('submissionDetails').innerHTML = detailsHtml;
|
||||
document.getElementById('downloadSubmissionBtn').onclick = () => downloadSubmission(submission.id);
|
||||
}
|
||||
|
||||
function formatFieldValue(value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value.join(', ');
|
||||
}
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
return JSON.stringify(value);
|
||||
}
|
||||
return value || 'N/A';
|
||||
}
|
||||
|
||||
function formatFileSize(bytes) {
|
||||
if (!bytes) return 'Unknown';
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
||||
return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
|
||||
}
|
||||
|
||||
function downloadSubmission(submissionId) {
|
||||
window.open(`/recruitment/api/submissions/${submissionId}/download/`, '_blank');
|
||||
}
|
||||
|
||||
function deleteSubmission(submissionId) {
|
||||
if (confirm('Are you sure you want to delete this submission? This action cannot be undone.')) {
|
||||
fetch(`/recruitment/api/submissions/${submissionId}/delete/`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'X-CSRFToken': getCsrfToken()
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
location.reload();
|
||||
} else {
|
||||
alert('Error deleting submission: ' + data.error);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('Error deleting submission');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function exportSubmissions(format) {
|
||||
window.open(`/recruitment/api/forms/{{ form.id }}/export/?format=${format}`, '_blank');
|
||||
}
|
||||
|
||||
function getCsrfToken() {
|
||||
const cookie = document.cookie.split(';').find(c => c.trim().startsWith('csrftoken='));
|
||||
return cookie ? cookie.split('=')[1] : '';
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
@ -2,7 +2,7 @@
|
||||
{% load static i18n form_filters %}
|
||||
|
||||
|
||||
{% block title %}All Submissions for {{ template.name }} - ATS{% endblock %}
|
||||
{% block title %}{% trans "All Submissions for" %} {{ template.name }} - ATS{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
{% load static i18n crispy_forms_tags %}
|
||||
|
||||
|
||||
{% block title %}Submissions for {{ template.name }} - ATS{% endblock %}
|
||||
{% block title %}{% trans "Submissions for" %} {{ template.name }} - ATS{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
{% load static i18n crispy_forms_tags %}
|
||||
|
||||
|
||||
{% block title %}Form Templates - {{ block.super }}{% endblock %}
|
||||
{% block title %}{% trans "Form Templates" %} - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
{% load i18n %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-outline-primary btn-sm view-toggle active" data-view="table" data-list-id="{{ list_id }}">
|
||||
<i class="fas fa-table me-1"></i> Table
|
||||
<i class="fas fa-table me-1"></i> {% trans "Table" %}
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-primary btn-sm view-toggle" data-view="card" data-list-id="{{ list_id }}">
|
||||
<i class="fas fa-th me-1"></i> Card
|
||||
<i class="fas fa-th me-1"></i> {% trans "Card" %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<div class="card mt-4">
|
||||
<div class="card-header text-primary-theme">
|
||||
<h5 class="card-title mb-0">Add Comment</h5>
|
||||
<h5 class="card-title mb-0">{% trans "Add Comment" %}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="post" action="{% url 'add_meeting_comment' meeting.slug %}">
|
||||
@ -15,7 +15,7 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Add Comment</button>
|
||||
<button type="submit" class="btn btn-primary">{% trans "Add Comment" %}</button>
|
||||
{% if 'HX-Request' in request.headers %}
|
||||
<button type="button" class="btn btn-secondary" hx-get="{% url 'meeting_details' meeting.slug %}" hx-select="#comment-section" hx-target="#comment-section">Cancel</button>
|
||||
{% endif %}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<div id="comment-section">
|
||||
<div class="card mt-4">
|
||||
<div class="card-header text-primary-theme d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0">Comments ({{ comments.count }})</h5>
|
||||
<h5 class="card-title mb-0">{% trans "Comments" %} ({{ comments.count }})</h5>
|
||||
{% if 'HX-Request' in request.headers %}
|
||||
<button type="button" class="btn btn-light btn-sm" hx-get="{% url 'meeting_details' meeting.slug %}" hx-select="#comment-section" hx-target="#comment-section">
|
||||
<i class="bi bi-x-lg"></i> Close
|
||||
<i class="bi bi-x-lg"></i> {% trans "Close" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
@ -18,7 +18,7 @@
|
||||
<div>
|
||||
<strong>{{ comment.author.get_full_name|default:comment.author.username }}</strong>
|
||||
{% if comment.author != user %}
|
||||
<span class="badge bg-secondary ms-2">Comment</span>
|
||||
<span class="badge bg-secondary ms-2">{% trans "Comment" %}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<small class="text-muted">{{ comment.created_at|date:"M d, Y P" }}</small>
|
||||
@ -49,7 +49,7 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-muted">No comments yet. Be the first to comment!</p>
|
||||
<p class="text-muted">{% trans "No comments yet. Be the first to comment!" %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
<div class="card mt-4">
|
||||
<div class="card-header text-primary-theme">
|
||||
<h5 class="card-title mb-0">Delete Comment</h5>
|
||||
<h5 class="card-title mb-0">{% trans "Delete Comment" %}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Are you sure you want to delete this comment by <strong>{{ comment.author.get_full_name|default:comment.author.username }}</strong>?</p>
|
||||
<p>{% trans "Are you sure you want to delete this comment by" %} <strong>{{ comment.author.get_full_name|default:comment.author.username }}</strong>?</p>
|
||||
<p><small>{{ comment.created_at|date:"F d, Y P" }}</small></p>
|
||||
<form method="post" action="{{ delete_url }}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-danger">Yes, Delete</button>
|
||||
<button type="submit" class="btn btn-danger">{% trans "Yes, Delete" %}</button>
|
||||
{% if 'HX-Request' in request.headers %}
|
||||
<button type="button" class="btn btn-secondary" hx-get="{% url 'meeting_details' meeting.slug %}" hx-select="#comment-section" hx-target="#comment-section">Cancel</button>
|
||||
<button type="button" class="btn btn-secondary" hx-get="{% url 'meeting_details' meeting.slug %}" hx-select="#comment-section" hx-target="#comment-section">{% trans "Cancel" %}</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<div class="card mt-4">
|
||||
<div class="card-header text-primary-theme">
|
||||
<h5 class="card-title mb-0">Edit Comment</h5>
|
||||
<h5 class="card-title mb-0">{% trans "Edit Comment" %}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="post" action="{% url 'edit_meeting_comment' meeting.slug comment.id %}">
|
||||
@ -15,9 +15,9 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<button type="submit" class="btn bg-primary btn-sm">Update Comment</button>
|
||||
<button type="submit" class="btn bg-primary btn-sm">{% trans "Update Comment" %}</button>
|
||||
{% if 'HX-Request' in request.headers %}
|
||||
<button type="button" class="btn btn-secondary btn-sm" hx-get="{% url 'meeting_details' meeting.slug %}" hx-target="#comment-section">Cancel</button>
|
||||
<button type="button" class="btn btn-secondary btn-sm" hx-get="{% url 'meeting_details' meeting.slug %}" hx-target="#comment-section">{% trans "Cancel" %}</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -7,41 +7,41 @@
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h5>Select Candidates</h5>
|
||||
<h5>{% trans "Select Candidates" %}</h5>
|
||||
<div class="form-group">
|
||||
{{ form.candidates }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<h5>Schedule Details</h5>
|
||||
<h5>{% trans "Schedule Details" %}</h5>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="{{ form.start_date.id_for_label }}">Start Date</label>
|
||||
<label for="{{ form.start_date.id_for_label }}">{% trans "Start Date" %}</label>
|
||||
{{ form.start_date }}
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="{{ form.end_date.id_for_label }}">End Date</label>
|
||||
<label for="{{ form.end_date.id_for_label }}">{% trans "End Date" %}</label>
|
||||
{{ form.end_date }}
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label>Working Days</label>
|
||||
<label>{% trans "Working Days" %}</label>
|
||||
{{ form.working_days }}
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group mb-3">
|
||||
<label for="{{ form.start_time.id_for_label }}">Start Time</label>
|
||||
<label for="{{ form.start_time.id_for_label }}">{% trans "Start Time" %}</label>
|
||||
{{ form.start_time }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="form-group mb-3">
|
||||
<label for="{{ form.end_time.id_for_label }}">End Time</label>
|
||||
<label for="{{ form.end_time.id_for_label }}">{% trans "End Time" %}</label>
|
||||
{{ form.end_time }}
|
||||
</div>
|
||||
</div>
|
||||
@ -50,14 +50,14 @@
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group mb-3">
|
||||
<label for="{{ form.interview_duration.id_for_label }}">Interview Duration (minutes)</label>
|
||||
<label for="{{ form.interview_duration.id_for_label }}">{% trans "Interview Duration (minutes)" %}</label>
|
||||
{{ form.interview_duration }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="form-group mb-3">
|
||||
<label for="{{ form.buffer_time.id_for_label }}">Buffer Time (minutes)</label>
|
||||
<label for="{{ form.buffer_time.id_for_label }}">{% trans "Buffer Time (minutes)" %}</label>
|
||||
{{ form.buffer_time }}
|
||||
</div>
|
||||
</div>
|
||||
@ -73,28 +73,28 @@
|
||||
{% for form in break_formset %}
|
||||
<div class="break-time-form row mb-2">
|
||||
<div class="col-md-5">
|
||||
<label>Start Time</label>
|
||||
<label>{% trans "Start Time" %}</label>
|
||||
{{ form.start_time }}
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<label>End Time</label>
|
||||
<label>{% trans "End Time" %}</label>
|
||||
{{ form.end_time }}
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label> </label><br>
|
||||
{{ form.DELETE }}
|
||||
<button type="button" class="btn btn-danger btn-sm remove-break">Remove</button>
|
||||
<button type="button" class="btn btn-danger btn-sm remove-break">{% trans "Remove" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<button type="button" id="add-break" class="btn btn-secondary btn-sm mt-2">Add Break</button>
|
||||
<button type="button" id="add-break" class="btn btn-secondary btn-sm mt-2">{% trans "Add Break" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<button type="submit" class="btn btn-primary">Preview Schedule</button>
|
||||
<a href="{% url 'job_detail' slug=job.slug %}" class="btn btn-secondary">Cancel</a>
|
||||
<button type="submit" class="btn btn-primary">{% trans "Preview Schedule" %}</button>
|
||||
<a href="{% url 'job_detail' slug=job.slug %}" class="btn btn-secondary">{% trans "Cancel" %}</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -1,499 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static i18n %}
|
||||
{% load widget_tweaks %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
:root {
|
||||
--kaauh-teal: #00636e;
|
||||
--kaauh-teal-dark: #004a53;
|
||||
--kaauh-teal-light: #e0f7f9;
|
||||
--kaauh-border: #e9ecef;
|
||||
--kaauh-primary-text: #212529;
|
||||
--kaauh-secondary-text: #6c757d;
|
||||
--kaauh-gray-light: #f8f9fa;
|
||||
--kaauh-success: #198754;
|
||||
--kaauh-danger: #dc3545;
|
||||
--kaauh-link: #007bff;
|
||||
--kaauh-link-hover: #0056b3;
|
||||
}
|
||||
body { background-color: #f0f2f5; font-family: 'Inter', sans-serif; }
|
||||
.card { border: none; border-radius: 8px; box-shadow: 0 3px 10px rgba(0,0,0,0.04); margin-bottom: 1rem; }
|
||||
.card-body { padding: 1rem 1.25rem; }
|
||||
#comments-card .card-header {
|
||||
background-color: white;
|
||||
color: var(--kaauh-teal-dark);
|
||||
padding: 0.75rem 1.25rem;
|
||||
font-weight: 600;
|
||||
border-radius: 8px 8px 0 0;
|
||||
border-bottom: 1px solid var(--kaauh-border);
|
||||
}
|
||||
.main-title-container h1 {
|
||||
font-size: 1.75rem; font-weight: 700;
|
||||
}
|
||||
.status-badge {
|
||||
font-size: 0.7rem; padding: 0.3em 0.7em; border-radius: 12px;
|
||||
}
|
||||
.bg-scheduled { background-color: #00636e !important; color: white !important; }
|
||||
.bg-completed { background-color: #198754 !important; color: white !important; }
|
||||
.bg-waiting { background-color: #ffc107 !important; color: var(--kaauh-primary-text) !important; }
|
||||
.bg-started { background-color: var(--kaauh-teal) !important; color: white !important; }
|
||||
.bg-ended { background-color: var(--kaauh-danger) !important; color: white !important; }
|
||||
.bg-cancelled { background-color: #6c757d !important; color: white !important; }
|
||||
|
||||
.detail-section h2, .card h2 {
|
||||
color: var(--kaauh-teal-dark); font-weight: 700; font-size: 1.25rem;
|
||||
margin-bottom: 0.75rem; padding-bottom: 0.5rem; border-bottom: 1px solid var(--kaauh-border);
|
||||
}
|
||||
.detail-row-simple {
|
||||
display: flex; padding: 0.4rem 0; border-bottom: 1px dashed var(--kaauh-border); font-size: 0.85rem;
|
||||
}
|
||||
.detail-label-simple { font-weight: 600; color: var(--kaauh-teal-dark); flex-basis: 40%; }
|
||||
.detail-value-simple { color: var(--kaauh-primary-text); font-weight: 500; flex-basis: 60%; }
|
||||
.btn-primary-teal {
|
||||
background-color: var(--kaauh-teal); border-color: var(--kaauh-teal); padding: 0.6rem 1.2rem;
|
||||
font-size: 0.95rem; border-radius: 6px; color: white;
|
||||
}
|
||||
.btn-primary-teal:hover { background-color: var(--kaauh-teal-dark); }
|
||||
.btn-danger-red {
|
||||
background-color: var(--kaauh-danger); border-color: var(--kaauh-danger); color: white;
|
||||
padding: 0.6rem 1.2rem; font-size: 0.95rem; border-radius: 6px; font-weight: 600;
|
||||
}
|
||||
.btn-danger-red:hover { background-color: #c82333; border-color: #bd2130; }
|
||||
.btn-secondary-back {
|
||||
background-color: transparent; border: none; color: var(--kaauh-secondary-text);
|
||||
font-weight: 600; font-size: 1rem; padding: 0.5rem 0.75rem; transition: color 0.2s;
|
||||
}
|
||||
.btn-secondary-back:hover { color: var(--kaauh-teal); text-decoration: underline; }
|
||||
.join-url-display {
|
||||
background-color: white; border: 1px solid var(--kaauh-border); padding: 0.5rem; font-size: 0.85rem;
|
||||
}
|
||||
.btn-copy-simple {
|
||||
padding: 0.5rem 0.75rem; background-color: var(--kaauh-teal-dark); border: none; color: white; border-radius: 4px;
|
||||
}
|
||||
.btn-copy-simple:hover { background-color: var(--kaauh-teal); }
|
||||
.simple-table {
|
||||
width: 100%; margin-top: 0.5rem; border-collapse: collapse;
|
||||
}
|
||||
.simple-table th {
|
||||
background-color: var(--kaauh-teal); color: white; font-weight: 700;
|
||||
padding: 8px 12px; border: 1px solid var(--kaauh-border); font-size: 0.8rem;
|
||||
}
|
||||
.simple-table td {
|
||||
padding: 8px 12px; border: 1px solid var(--kaauh-border); background-color: white; font-size: 0.85rem;
|
||||
}
|
||||
.comment-item { border: 1px solid var(--kaauh-border); background-color: var(--kaauh-gray-light); border-radius: 6px; }
|
||||
.btn-edit-comment {
|
||||
background-color: transparent; border: 1px solid var(--kaauh-teal); color: var(--kaauh-teal);
|
||||
padding: 0.25rem 0.5rem; font-size: 0.75rem; border-radius: 4px; font-weight: 500;
|
||||
}
|
||||
.btn-edit-comment:hover { background-color: var(--kaauh-teal-light); }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid py-4">
|
||||
|
||||
{# --- TOP BAR --- #}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<a href="{% url 'list_meetings' %}" class="btn btn-secondary-back">
|
||||
<i class="fas fa-arrow-left me-1"></i> {% trans "Back to Meetings" %}
|
||||
</a>
|
||||
<div class="d-flex gap-2">
|
||||
<a href="{% url 'update_meeting' meeting.slug %}" class="btn btn-primary-teal btn-sm">
|
||||
<i class="fas fa-edit me-1"></i> {% trans "Edit Meeting" %}
|
||||
</a>
|
||||
<form method="post" action="{% url 'delete_meeting' meeting.slug %}" style="display: inline;">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-danger-red btn-sm" onclick="return confirm('{% trans "Are you sure you want to delete this meeting? This action is permanent." %}')">
|
||||
<i class="fas fa-trash-alt me-1"></i> {% trans "Delete Meeting" %}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# --- MAIN TITLE --- #}
|
||||
<div class="main-title-container mb-4">
|
||||
<h1 class="text-start" style="color: var(--kaauh-teal-dark);">
|
||||
<i class="fas fa-video me-2" style="color: var(--kaauh-teal);"></i>
|
||||
{{ meeting.topic|default:"[Meeting Topic]" }}
|
||||
<span class="status-badge bg-{{ interview.status|lower|default:'scheduled' }} ms-3">
|
||||
{{ interview.get_status_display|default:"Scheduled" }}
|
||||
</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{# --- INTERVIEW & CONNECTION CARDS --- #}
|
||||
<div class="row g-4 mb-5 align-items-stretch">
|
||||
{# Interview Detail #}
|
||||
<div class="col-lg-6">
|
||||
<div class="p-3 bg-white rounded shadow-sm h-100 d-flex flex-column">
|
||||
<h2 class="text-start"><i class="fas fa-briefcase me-2"></i> {% trans "Interview Detail" %}</h2>
|
||||
<div class="detail-row-group flex-grow-1">
|
||||
<div class="detail-row-simple">
|
||||
<div class="detail-label-simple">{% trans "Job Title" %}:</div>
|
||||
<div class="detail-value-simple">{{ job.title|default:"N/A" }}</div>
|
||||
</div>
|
||||
<div class="detail-row-simple">
|
||||
<div class="detail-label-simple">{% trans "Candidate Name" %}:</div>
|
||||
<div class="detail-value-simple">{{ candidate.full_name|default:"N/A" }}</div>
|
||||
</div>
|
||||
<div class="detail-row-simple">
|
||||
<div class="detail-label-simple">{% trans "Candidate Email" %}:</div>
|
||||
<div class="detail-value-simple">{{ candidate.email|default:"N/A" }}</div>
|
||||
</div>
|
||||
<div class="detail-row-simple">
|
||||
<div class="detail-label-simple">{% trans "Job Type" %}:</div>
|
||||
<div class="detail-value-simple">{{ job.job_type|default:"N/A" }}</div>
|
||||
</div>
|
||||
{% if candidate.belong_to_agency %}
|
||||
<div class="detail-row-simple">
|
||||
<div class="detail-label-simple">{% trans "Agency" %}:</div>
|
||||
<div class="detail-value-simple">{{ candidate.hiring_agency.name|default:"N/A" }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Connection Details #}
|
||||
<div class="col-lg-6">
|
||||
<div class="p-3 bg-white rounded shadow-sm h-100 d-flex flex-column">
|
||||
<h2 class="text-start"><i class="fas fa-info-circle me-2"></i> {% trans "Connection Details" %}</h2>
|
||||
<div class="detail-row-group flex-grow-1">
|
||||
<div class="detail-row-simple">
|
||||
<div class="detail-label-simple">{% trans "Date & Time" %}:</div>
|
||||
<div class="detail-value-simple">
|
||||
{{ interview.interview_date }} {{ interview.interview_time }} ({{ meeting.timezone }})
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-row-simple">
|
||||
<div class="detail-label-simple">{% trans "Duration" %}:</div>
|
||||
<div class="detail-value-simple">
|
||||
{% if meeting.location_type == "Remote" %}
|
||||
{{ meeting.zoommeetingdetails.duration|default:"N/A" }}
|
||||
{% elif meeting.location_type == "Onsite" %}
|
||||
{{ meeting.onsitelocationdetails.duration|default:"N/A" }}
|
||||
{% else %}
|
||||
N/A
|
||||
{% endif %}
|
||||
{% trans "minutes" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if meeting.location_type == "Remote" %}
|
||||
{% with zoom=meeting.zoommeetingdetails %}
|
||||
<div class="detail-row-simple">
|
||||
<div class="detail-label-simple">{% trans "Meeting ID" %}:</div>
|
||||
<div class="detail-value-simple">{{ zoom.meeting_id|default:"N/A" }}</div>
|
||||
</div>
|
||||
<div class="detail-row-simple">
|
||||
<div class="detail-label-simple">{% trans "Host Email" %}:</div>
|
||||
<div class="detail-value-simple">{{ zoom.host_email|default:"N/A" }}</div>
|
||||
</div>
|
||||
{% if meeting.details_url %}
|
||||
<div class="join-url-container pt-3" style="position: relative;">
|
||||
<div id="copy-message" class="text-white rounded px-2 py-1 small fw-bold mb-2 text-center" style="opacity: 0; transition: opacity 0.3s; position: absolute; right: 0; top: -35px; background-color: var(--kaauh-success); z-index: 10;">
|
||||
{% trans "Copied!" %}
|
||||
</div>
|
||||
<div class="join-url-display d-flex justify-content-between align-items-center">
|
||||
<div class="text-truncate me-2">
|
||||
<strong>{% trans "Join URL" %}:</strong>
|
||||
<span id="meeting-join-url">{{ meeting.details_url }}</span>
|
||||
</div>
|
||||
<button class="btn-copy-simple ms-2 flex-shrink-0" onclick="copyLink()" title="{% trans 'Copy URL' %}">
|
||||
<i class="fas fa-copy"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% elif meeting.location_type == "Onsite" %}
|
||||
{% with onsite=meeting.onsitelocationdetails %}
|
||||
<div class="detail-row-simple">
|
||||
<div class="detail-label-simple">{% trans "Address" %}:</div>
|
||||
<div class="detail-value-simple">{{ onsite.physical_address|default:"N/A" }}</div>
|
||||
</div>
|
||||
<div class="detail-row-simple">
|
||||
<div class="detail-label-simple">{% trans "Room" %}:</div>
|
||||
<div class="detail-value-simple">{{ onsite.room_number|default:"TBD" }}</div>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# --- PARTICIPANTS --- #}
|
||||
{% comment %} <div class="row g-4 mt-1 mb-5">
|
||||
<div class="col-lg-12">
|
||||
<div class="p-3 bg-white rounded shadow-sm">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h2 class="text-start"><i class="fas fa-users-cog me-2"></i> {% trans "Assigned Participants" %}</h2>
|
||||
<div class="d-flex gap-2">
|
||||
<button type="button" class="btn btn-primary-teal btn-sm"
|
||||
data-bs-toggle="modal" data-bs-target="#assignParticipants">
|
||||
<i class="fas fa-users-cog me-1"></i> {% trans "Manage Participants" %} ({{ total_participants }})
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-info" data-bs-toggle="modal" data-bs-target="#emailModal">
|
||||
<i class="fas fa-envelope"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="simple-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Name" %}</th>
|
||||
<th>{% trans "Role" %}</th>
|
||||
<th>{% trans "Email" %}</th>
|
||||
<th>{% trans "Phone" %}</th>
|
||||
<th>{% trans "Type" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for participant in external_participants %}
|
||||
<tr>
|
||||
<td>{{ participant.name }}</td>
|
||||
<td>{{ participant.designation|default:"Participant" }}</td>
|
||||
<td>{{ participant.email|default:"N/A" }}</td>
|
||||
<td>{{ participant.phone|default:"N/A" }}</td>
|
||||
<td>{% trans "External" %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% for user in system_participants %}
|
||||
<tr>
|
||||
<td>{{ user.get_full_name|default:user.username }}</td>
|
||||
<td>Admin</td>
|
||||
<td>{{ user.email|default:"N/A" }}</td>
|
||||
<td>{{ user.phone|default:"N/A" }}</td>
|
||||
<td>{% trans "System User" %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div> {% endcomment %}
|
||||
|
||||
{# --- COMMENTS --- #}
|
||||
<div class="row g-4 mt-1">
|
||||
<div class="col-lg-12">
|
||||
<div class="card" id="comments-card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0">
|
||||
<i class="fas fa-comments me-2"></i>
|
||||
{% trans "Comments" %} ({{ interview.notes.count }})
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="comment-section" class="mb-4">
|
||||
{% for note in interview.notes.all|dictsortreversed:"created_at" %}
|
||||
<div class="comment-item mb-3 p-3">
|
||||
<div id="comment-view-{{ note.pk }}">
|
||||
<div class="d-flex justify-content-between align-items-start mb-2">
|
||||
<div class="comment-metadata" style="font-size: 0.9rem;">
|
||||
<strong>{{ note.author.get_full_name|default:note.author.username }}</strong>
|
||||
<span class="text-muted small ms-2">{{ note.created_at|date:"M d, Y H:i" }}</span>
|
||||
</div>
|
||||
{% if note.author == user or user.is_staff %}
|
||||
<div class="comment-actions d-flex align-items-center gap-1">
|
||||
<button type="button" class="btn btn-edit-comment py-0 px-1" onclick="toggleCommentEdit('{{ note.pk }}')" id="edit-btn-{{ note.pk }}">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
<form method="post" action="{% url 'delete_meeting_comment' meeting.slug note.pk %}" style="display: inline;">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-outline-danger py-0 px-1" onclick="return confirm('{% trans "Are you sure you want to delete this comment?" %}')">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p class="mb-0" style="font-size: 0.85rem; white-space: pre-wrap;">{{ note.content|linebreaksbr }}</p>
|
||||
</div>
|
||||
|
||||
<div id="comment-edit-form-{{ note.pk }}" style="display: none; margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--kaauh-border);">
|
||||
<form method="POST" action="{% url 'edit_meeting_comment' meeting.slug note.pk %}">
|
||||
{% csrf_token %}
|
||||
<div class="mb-2">
|
||||
<label class="form-label small">{% trans "Edit Comment" %}</label>
|
||||
<textarea name="content" class="form-control" rows="3" required>{{ note.content }}</textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success btn-sm me-2">
|
||||
<i class="fas fa-save me-1"></i> {% trans "Save Changes" %}
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary btn-sm" onclick="toggleCommentEdit('{{ note.pk }}')">
|
||||
{% trans "Cancel" %}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% empty %}
|
||||
<p class="text-muted">{% trans "No comments yet. Be the first to comment!" %}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<h6 class="mb-3">{% trans "Add a New Comment" %}</h6>
|
||||
<form method="POST" action="{% url 'add_meeting_comment' meeting.slug %}">
|
||||
{% csrf_token %}
|
||||
<div class="mb-3">
|
||||
<label class="form-label small">{% trans "Comment" %}</label>
|
||||
<textarea name="content" class="form-control" rows="3" required></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary-teal btn-sm">
|
||||
<i class="fas fa-paper-plane me-1"></i> {% trans "Submit Comment" %}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# MODALS #}
|
||||
<!-- Participants Modal -->
|
||||
<div class="modal fade" id="assignParticipants" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">{% trans "Manage all participants" %}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form method="post" action="{% url 'create_interview_participants' interview.slug %}">
|
||||
{% csrf_token %}
|
||||
<div class="modal-body table-responsive">
|
||||
|
||||
{{ meeting.name }}
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
|
||||
<table class="table tab table-bordered mt-3">
|
||||
<thead>
|
||||
<th class="col">👥 {% trans "Participants" %}</th>
|
||||
<th class="col">🧑💼 {% trans "Users" %}</th>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
{{ form.participants.errors }}
|
||||
{{ form.participants }}
|
||||
</td>
|
||||
<td> {{ form.system_users.errors }}
|
||||
{{ form.system_users }}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger-red" data-bs-dismiss="modal">{% trans "Close" %}</button>
|
||||
<button type="submit" class="btn btn-primary-teal">{% trans "Save" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Email Modal -->
|
||||
<div class="modal fade" id="emailModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-light">
|
||||
<h5 class="modal-title">📧 {% trans "Compose Interview Invitation" %}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form method="post" action="{% url 'send_interview_email' interview.slug %}">
|
||||
{% csrf_token %}
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-bold">{% trans "Subject" %}</label>
|
||||
{{ email_form.subject|add_class:"form-control" }}
|
||||
</div>
|
||||
<ul class="nav nav-tabs" id="messageTabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="candidate-tab" data-bs-toggle="tab" data-bs-target="#candidate-pane" type="button">
|
||||
{% if candidate.belong_to_agency %}
|
||||
{% trans "Agency Message" %}
|
||||
{% else %}
|
||||
{% trans "Candidate Message" %}
|
||||
{% endif %}
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="participants-tab" data-bs-toggle="tab" data-bs-target="#participants-pane" type="button">
|
||||
{% trans "Panel Message" %}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content border border-top-0 p-3 bg-light-subtle">
|
||||
<div class="tab-pane fade show active" id="candidate-pane">
|
||||
<p class="text-muted small">
|
||||
{% if candidate.belong_to_agency %}
|
||||
{% trans "This email will be sent to the hiring agency." %}
|
||||
{% else %}
|
||||
{% trans "This email will be sent to the candidate." %}
|
||||
{% endif %}
|
||||
</p>
|
||||
{% if candidate.belong_to_agency %}
|
||||
{{ email_form.message_for_agency|add_class:"form-control" }}
|
||||
{% else %}
|
||||
{{ email_form.message_for_candidate|add_class:"form-control" }}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="tab-pane fade" id="participants-pane">
|
||||
<p class="text-muted small">{% trans "This email will be sent to all interview participants." %}</p>
|
||||
{{ email_form.message_for_participants|add_class:"form-control" }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger-red" data-bs-dismiss="modal">{% trans "Close" %}</button>
|
||||
<button type="submit" class="btn btn-primary-teal">{% trans "Send Invitation" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block customJS %}
|
||||
<script>
|
||||
function toggleCommentEdit(commentPk) {
|
||||
const viewDiv = document.getElementById(`comment-view-${commentPk}`);
|
||||
const editFormDiv = document.getElementById(`comment-edit-form-${commentPk}`);
|
||||
if (viewDiv.style.display === 'none') {
|
||||
viewDiv.style.display = 'block';
|
||||
editFormDiv.style.display = 'none';
|
||||
} else {
|
||||
viewDiv.style.display = 'none';
|
||||
editFormDiv.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
function copyLink() {
|
||||
const urlElement = document.getElementById('meeting-join-url');
|
||||
const textToCopy = urlElement.textContent || urlElement.innerText;
|
||||
const messageElement = document.getElementById('copy-message');
|
||||
|
||||
navigator.clipboard.writeText(textToCopy).then(() => {
|
||||
messageElement.style.opacity = '1';
|
||||
setTimeout(() => {
|
||||
messageElement.style.opacity = '0';
|
||||
}, 2000);
|
||||
}).catch(err => {
|
||||
console.error('Failed to copy: ', err);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
@ -11,7 +11,7 @@
|
||||
<div class="card-header">
|
||||
<h4 class="mb-0">
|
||||
<i class="fas fa-building me-2"></i>
|
||||
Create Onsite Interview for {{ application.name }}
|
||||
{% trans "Create Onsite Interview for" %} {{ application.name }}
|
||||
</h4>
|
||||
<a href="{% url 'interview_create_type_selection' application.slug %}"
|
||||
class="btn btn-outline-primary">
|
||||
@ -21,8 +21,8 @@
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted mb-3">
|
||||
Schedule an onsite interview for <strong>{{ application.name }}</strong>
|
||||
for the position of <strong>{{ job.title }}</strong>.
|
||||
{% trans "Schedule an onsite interview for" %} <strong>{{ application.name }}</strong>
|
||||
{% trans "for the position of" %} <strong>{{ job.title }}</strong>.
|
||||
</p>
|
||||
|
||||
{% if messages %}
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
<div class="card-header">
|
||||
<h4 class="mb-0">
|
||||
<i class="fas fa-video me-2"></i>
|
||||
Create Remote Interview for {{ application.name }}
|
||||
{% trans "Create Remote Interview for" %} {{ application.name }}
|
||||
</h4>
|
||||
<a href="{% url 'interview_create_type_selection' application.slug %}"
|
||||
class="btn btn-outline-primary">
|
||||
@ -21,8 +21,8 @@
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted mb-3">
|
||||
Schedule a remote interview for <strong>{{ application.name }}</strong>
|
||||
for the position of <strong>{{ job.title }}</strong>.
|
||||
{% trans "Schedule a remote interview for" %} <strong>{{ application.name }}</strong>
|
||||
{% trans "for the position of" %} <strong>{{ job.title }}</strong>.
|
||||
</p>
|
||||
|
||||
{% if messages %}
|
||||
|
||||
@ -11,13 +11,13 @@
|
||||
<div class="card-header">
|
||||
<h4 class="mb-0">
|
||||
<i class="fas fa-calendar-plus me-2"></i>
|
||||
Create Interview for {{ application.name }}
|
||||
{% trans "Create Interview for" %} {{ application.name }}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="card-body" hx-boost="true" hx-push-url="false" hx-select=".card-body" hx-swap="innerHTML" hx-target="#candidateviewModalBody">
|
||||
<p class="text-muted mb-3">
|
||||
Select the type of interview you want to schedule for <strong>{{ application.name }}</strong>
|
||||
for the position of <strong>{{ job.title }}</strong>.
|
||||
{% trans "Select the type of interview you want to schedule for" %} <strong>{{ application.name }}</strong>
|
||||
{% trans "for the position of" %} <strong>{{ job.title }}</strong>.
|
||||
</p>
|
||||
|
||||
<div class="d-grid gap-3" style="grid-template-columns: 1fr 1fr;">
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Interview Management" %} - ATS{% endblock %}
|
||||
{% block title %}{% trans "Interviews" %} - ATS{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
<div class="col-lg-6 col-md-8">
|
||||
<div class="card shadow-lg border-0 rounded-lg mt-5">
|
||||
<div class="card-header bg-main-action text-white">
|
||||
<h3 class="text-center font-weight-light my-4">Set Interview Location</h3>
|
||||
<h3 class="text-center font-weight-light my-4">{% trans "Set Interview Location" %}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="post" action="{% url 'confirm_schedule_interviews_view' job.slug %}" enctype="multipart/form-data">
|
||||
@ -18,12 +18,12 @@
|
||||
<div class="d-flex align-items-center justify-content-between mt-4 mb-0">
|
||||
|
||||
<a href="{% url 'list_meetings' %}" class="btn btn-secondary me-2">
|
||||
<i class="fas fa-times me-1"></i> Close
|
||||
<i class="fas fa-times me-1"></i> {% trans "Close" %}
|
||||
</a>
|
||||
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-save me-1"></i> Save Location
|
||||
<i class="fas fa-save me-1"></i> {% trans "Save Location" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td><a class="btn btn-outline-primary btn-sm" href="{% url 'interview_detail' interview.slug %}" target="_blank">View</a></td>
|
||||
<td><a class="btn btn-outline-primary btn-sm" href="{% url 'interview_detail' interview.slug %}" target="_blank">{% trans "View" %}</a></td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static crispy_forms_tags %}
|
||||
{%load i18n %}
|
||||
|
||||
{% block title%} {% trans "Preview Interview Schedule" %}{%endblock%}
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
/* Custom Teal Theme Variables (Adapt these if defined globally) */
|
||||
@ -90,7 +90,7 @@
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-5">
|
||||
<h1 class="h3 page-header">
|
||||
<i class="fas fa-calendar-alt me-2 text-primary-theme"></i> Interview Schedule Preview: **{{ job.title }}**
|
||||
<i class="fas fa-calendar-alt me-2 text-primary-theme"></i> {% trans "Interview Schedule Preview:"%}" **{{ job.title }}**
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
@ -100,14 +100,14 @@
|
||||
<div class="row g-4">
|
||||
|
||||
<div class="col-md-6">
|
||||
<p class="mb-2"><strong><i class="fas fa-clock me-2 text-primary-theme"></i> Working Hours:</strong> {{ start_time|time:"g:i A" }} to {{ end_time|time:"g:i A" }}</p>
|
||||
<p class="mb-2"><strong><i class="fas fa-hourglass-half me-2 text-primary-theme"></i> Interview Duration:</strong> {{ interview_duration }} minutes</p>
|
||||
<p class="mb-2"><strong><i class="fas fa-shield-alt me-2 text-primary-theme"></i> Buffer Time:</strong> {{ buffer_time }} minutes</p>
|
||||
<p class="mb-2"><strong><i class="fas fa-clock me-2 text-primary-theme"></i>{% trans "Working Hours:" %}</strong> {{ start_time|time:"g:i A" }} to {{ end_time|time:"g:i A" }}</p>
|
||||
<p class="mb-2"><strong><i class="fas fa-hourglass-half me-2 text-primary-theme"></i> {% trans "Interview Duration:" %}</strong> {{ interview_duration }} {% trans "minutes" %}</p>
|
||||
<p class="mb-2"><strong><i class="fas fa-shield-alt me-2 text-primary-theme"></i>{% trans "Buffer Time:" %}</strong> {{ buffer_time }} {% trans "minutes" %}</p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<p class="mb-2"><strong><i class="fas fa-calendar-day me-2 text-primary-theme"></i> Interview Period:</strong> {{ start_date|date:"F j, Y" }} — {{ end_date|date:"F j, Y" }}</p>
|
||||
<p class="mb-2"><strong><i class="fas fa-list-check me-2 text-primary-theme"></i> Active Days:</strong>
|
||||
<p class="mb-2"><strong><i class="fas fa-calendar-day me-2 text-primary-theme"></i>{% trans "Interview Period:" %}</strong> {{ start_date|date:"F j, Y" }} — {{ end_date|date:"F j, Y" }}</p>
|
||||
<p class="mb-2"><strong><i class="fas fa-list-check me-2 text-primary-theme"></i>{% trans "Active Days:" %}</strong>
|
||||
{% for day_id in working_days %}
|
||||
{% if day_id == 0 %}Mon{% endif %}
|
||||
{% if day_id == 1 %}Tue{% endif %}
|
||||
@ -119,7 +119,7 @@
|
||||
{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
<p class="mb-2"><strong><i class="fas fa-calendar-day me-2 text-primary-theme"></i> Interview Type:</strong> {{schedule_interview_type}}</p>
|
||||
<p class="mb-2"><strong><i class="fas fa-calendar-day me-2 text-primary-theme"></i>{% trans "Interview Type:" %}</strong> {{schedule_interview_type}}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -134,7 +134,7 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="mt-3"><small class="text-muted"><i class="fas fa-exclamation-circle me-1"></i> No daily breaks scheduled.</small></p>
|
||||
<p class="mt-3"><small class="text-muted"><i class="fas fa-exclamation-circle me-1"></i> {% trans "No daily breaks scheduled." %}</small></p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@ -152,10 +152,10 @@
|
||||
<table class="table table-hover table-striped">
|
||||
<thead class="bg-primary-theme-light">
|
||||
<tr>
|
||||
<th scope="col">Date</th>
|
||||
<th scope="col">Time</th>
|
||||
<th scope="col">Candidate</th>
|
||||
<th scope="col">Email</th>
|
||||
<th scope="col">{% trans "Date" %}</th>
|
||||
<th scope="col">{% trans "Time" %}</th>
|
||||
<th scope="col">{% trans "Applicant" %}</th>
|
||||
<th scope="col">{% trans "Email" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -202,10 +202,10 @@
|
||||
<div class="modal-footer">
|
||||
<div class="d-flex align-items-center justify-content-between mt-4 mb-0">
|
||||
<a href="#" class="btn btn-secondary me-2">
|
||||
<i class="fas fa-times me-1"></i> Close
|
||||
<i class="fas fa-times me-1"></i> {% trans "Close" %}
|
||||
</a>
|
||||
<button type="submit" class="btn btn-primary" form="onsite-form">
|
||||
<i class="fas fa-save me-1"></i> Save Location
|
||||
<i class="fas fa-save me-1"></i> {% trans "Save Location" %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
{% load static i18n %}
|
||||
{% load widget_tweaks %}
|
||||
|
||||
{% block title %}Bulk Interview Scheduling - {{ job.title }} - ATS{% endblock %}
|
||||
{% block title %}{% trans "Bulk Interview Scheduling" %} - {{ job.title }} - ATS{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid py-4">
|
||||
|
||||
@ -1,33 +1,39 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}Apply for {{ job.title }} - University Careers{% endblock %}
|
||||
{% block title %}{% blocktrans %}Apply for {{ job.title }} - University Careers{% endblocktrans %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2><i class="fas fa-file-signature"></i> Apply for {{ job.title }}</h2>
|
||||
<p class="text-muted">{{ job.department }} • {{ job.get_location_display }}</p>
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h2 class="h4 mb-1">
|
||||
<i class="fas fa-file-signature"></i>
|
||||
{% blocktrans with job_title=job.title %}Apply for {{ job_title }}{% endblocktrans %}
|
||||
</h2>
|
||||
<p class="text-muted mb-0">
|
||||
{{ job.department }} • {{ job.get_location_display }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="card-body p-4">
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
|
||||
<h4>Personal Information</h4>
|
||||
<h4 class="mb-3">{% trans "Personal Information" %}</h4>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">First Name *</label>
|
||||
<label class="form-label">{% trans "First Name" %} *</label>
|
||||
{{ form.first_name }}
|
||||
{% if form.first_name.errors %}<div class="text-danger">{{ form.first_name.errors }}</div>{% endif %}
|
||||
{% if form.first_name.errors %}<div class="text-danger small">{{ form.first_name.errors }}</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Last Name *</label>
|
||||
<label class="form-label">{% trans "Last Name" %} *</label>
|
||||
{{ form.last_name }}
|
||||
{% if form.last_name.errors %}<div class="text-danger">{{ form.last_name.errors }}</div>{% endif %}
|
||||
{% if form.last_name.errors %}<div class="text-danger small">{{ form.last_name.errors }}</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -35,65 +41,65 @@
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Email *</label>
|
||||
<label class="form-label">{% trans "Email" %} *</label>
|
||||
{{ form.email }}
|
||||
{% if form.email.errors %}<div class="text-danger">{{ form.email.errors }}</div>{% endif %}
|
||||
{% if form.email.errors %}<div class="text-danger small">{{ form.email.errors }}</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Phone</label>
|
||||
<label class="form-label">{% trans "Phone" %}</label>
|
||||
{{ form.phone }}
|
||||
{% if form.phone.errors %}<div class="text-danger">{{ form.phone.errors }}</div>{% endif %}
|
||||
{% if form.phone.errors %}<div class="text-danger small">{{ form.phone.errors }}</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="mt-4">Documents</h4>
|
||||
<h4 class="mt-4 mb-3">{% trans "Documents" %}</h4>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Resume/CV * (PDF or Word)</label>
|
||||
<label class="form-label">{% trans "Resume/CV * (PDF or Word)" %}</label>
|
||||
{{ form.resume }}
|
||||
{% if form.resume.errors %}<div class="text-danger">{{ form.resume.errors }}</div>{% endif %}
|
||||
{% if form.resume.errors %}<div class="text-danger small">{{ form.resume.errors }}</div>{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Cover Letter (Optional)</label>
|
||||
<label class="form-label">{% trans "Cover Letter (Optional)" %}</label>
|
||||
{{ form.cover_letter }}
|
||||
{% if form.cover_letter.errors %}<div class="text-danger">{{ form.cover_letter.errors }}</div>{% endif %}
|
||||
{% if form.cover_letter.errors %}<div class="text-danger small">{{ form.cover_letter.errors }}</div>{% endif %}
|
||||
</div>
|
||||
|
||||
<h4 class="mt-4">Additional Information</h4>
|
||||
<h4 class="mt-4 mb-3">{% trans "Additional Information" %}</h4>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">LinkedIn Profile</label>
|
||||
<label class="form-label">{% trans "LinkedIn Profile" %}</label>
|
||||
{{ form.linkedin_profile }}
|
||||
{% if form.linkedin_profile.errors %}<div class="text-danger">{{ form.linkedin_profile.errors }}</div>{% endif %}
|
||||
{% if form.linkedin_profile.errors %}<div class="text-danger small">{{ form.linkedin_profile.errors }}</div>{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Portfolio/Website</label>
|
||||
<label class="form-label">{% trans "Portfolio/Website" %}</label>
|
||||
{{ form.portfolio_url }}
|
||||
{% if form.portfolio_url.errors %}<div class="text-danger">{{ form.portfolio_url.errors }}</div>{% endif %}
|
||||
{% if form.portfolio_url.errors %}<div class="text-danger small">{{ form.portfolio_url.errors }}</div>{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Salary Expectations</label>
|
||||
<label class="form-label">{% trans "Salary Expectations" %}</label>
|
||||
{{ form.salary_expectations }}
|
||||
{% if form.salary_expectations.errors %}<div class="text-danger">{{ form.salary_expectations.errors }}</div>{% endif %}
|
||||
{% if form.salary_expectations.errors %}<div class="text-danger small">{{ form.salary_expectations.errors }}</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Availability</label>
|
||||
<label class="form-label">{% trans "Availability" %}</label>
|
||||
{{ form.availability }}
|
||||
{% if form.availability.errors %}<div class="text-danger">{{ form.availability.errors }}</div>{% endif %}
|
||||
{% if form.availability.errors %}<div class="text-danger small">{{ form.availability.errors }}</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary w-100 mt-3">
|
||||
<i class="fas fa-paper-plane"></i> Submit Application
|
||||
<button type="submit" class="btn btn-primary w-100 mt-4 py-2">
|
||||
<i class="fas fa-paper-plane"></i> {% trans "Submit Application" %}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}Create New Job Post - {{ block.super }}{% endblock %}
|
||||
{% block title %}{% trans "Create New Job Posting" %} - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Create New Job Post" %} - {{ block.super }}{% endblock %}
|
||||
{% block title %}{% trans "Edit Job Posting" %} - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
|
||||
@ -115,7 +115,7 @@
|
||||
{% block content %}
|
||||
<div class="container-fluid py-4">
|
||||
<h1 class="h3 mb-4 text-primary fw-bold">
|
||||
<i class="fas fa-bullhorn me-2"></i> {% if form.instance.pk %} {% trans "Edit Job Posting" %} {% else %} {% trans "Create New Job Posting" %} {% endif %}
|
||||
<i class="fas fa-bullhorn me-2"></i> {% if form.instance.pk %} {% trans "Edit Job Posting" %} {% else %} {% trans "Edit Job Posting" %} {% endif %}
|
||||
</h1>
|
||||
|
||||
<form method="post" id="jobForm" class="mb-5" enctype="multipart/form-data">
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% block title %}{{ job.title }} - Applicants{% endblock %}
|
||||
{% block title %}{{ job.title }} - {% trans "Applicants" %}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{{ job.title }} - Applicants{% endblock %}
|
||||
{% block title %}{{ job.title }} - {% trans "Applicantions" %}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}Job Bank - All Opportunities{% endblock %}
|
||||
{% block title %}{% trans "Job Bank - All Opportunities" %}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}Job Postings - University ATS{% endblock %}
|
||||
{% block title %}{% trans "Job Postings" %} - University ATS{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -1,30 +1,30 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Delete Job - University ATS{% endblock %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Delete Job - University ATS" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-header bg-danger text-white">
|
||||
<h4><i class="fas fa-exclamation-triangle"></i> Delete Job Posting</h4>
|
||||
<h4><i class="fas fa-exclamation-triangle"></i> {% trans "Delete Job Posting" %}</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Are you sure you want to delete the job posting "<strong>{{ job.title }}</strong>"?</p>
|
||||
<p>{% trans "Are you sure you want to delete the job posting" %} "<strong>{{ job.title }}</strong>"?</p>
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<strong>This action cannot be undone.</strong> All associated data will be permanently removed.
|
||||
<strong>{% trans "This action cannot be undone."%}</strong> {% trans "All associated data will be permanently removed." %}"
|
||||
</div>
|
||||
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="d-flex justify-content-between">
|
||||
<a href="{% url 'job_list' %}" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Cancel
|
||||
<i class="fas fa-arrow-left"></i> {% trans "Cancel" %}
|
||||
</a>
|
||||
<button type="submit" class="btn btn-danger">
|
||||
<i class="fas fa-trash"></i> Delete Job
|
||||
<i class="fas fa-trash"></i> {% trans "Delete Job" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
{% load i18n %}
|
||||
<div class="modal fade mt-4" id="myModalForm" tabindex="-1" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myModalLabel">Add New Image for the Post</h5>
|
||||
<h5 class="modal-title" id="myModalLabel">{% trans "Add New Image for the Post" %}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@ -11,12 +12,12 @@
|
||||
{{ image_upload_form.as_p}}
|
||||
|
||||
{% if image_upload_form.instance.post_image %}
|
||||
<p>Current Image:</p>
|
||||
<p>{% trans "Current Image:" %}</p>
|
||||
<img src="{{ image_upload_form.instance.post_image.url }}" alt="Post Image" style="max-width: 200px;">
|
||||
{% endif %}
|
||||
<div class="modal-footer mt-2">
|
||||
<button type="button" class="btn btn-lg btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="submit" class="btn btn-main-action ">Save changes</button>
|
||||
<button type="button" class="btn btn-lg btn-secondary" data-bs-dismiss="modal">{% trans "Close" %}</button>
|
||||
<button type="submit" class="btn btn-main-action ">{% trans "Save changes" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
{% load crispy_forms_tags %}
|
||||
{% load i18n %}
|
||||
<div class="modal fade mt-4" id="linkedinData" tabindex="-1" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myModalLabel">Edit linkedin Post content</h5>
|
||||
<h5 class="modal-title" id="myModalLabel">{% trans "Edit linkedin Post content" %}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@ -11,8 +12,8 @@
|
||||
{% csrf_token %}
|
||||
{{ linkedin_content_form|crispy }}
|
||||
<div class="modal-footer mt-2">
|
||||
<button type="button" class="btn btn-lg btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="submit" class="btn btn-main-action ">Save changes</button>
|
||||
<button type="button" class="btn btn-lg btn-secondary" data-bs-dismiss="modal">{% trans "Close" %}</button>
|
||||
<button type="submit" class="btn btn-main-action ">{% trans "Save changes" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -80,7 +80,7 @@
|
||||
</div>
|
||||
{% if message.job %}
|
||||
<div class="col-md-6">
|
||||
<strong>Related Job:</strong>
|
||||
<strong>{% trans "Related Job:" %}</strong>
|
||||
{{ message.job.title }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@ -99,7 +99,7 @@
|
||||
{{ message.subject|truncatechars:50 }}
|
||||
</a>
|
||||
{% if message.parent_message %}
|
||||
<span class="badge bg-secondary ms-2">Reply</span>
|
||||
<span class="badge bg-secondary ms-2">{% trans "Reply" %}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n crispy_forms_tags %}
|
||||
|
||||
{% block title %}Create Participant - {{ block.super }}{% endblock %}
|
||||
{% block title %}{% trans "Create Participant" %} - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{{ participant.name }} - Participant Details{% endblock %}
|
||||
{% block title %}{{ participant.name }} - {% trans "Participant Details" %}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}Participants - {{ block.super }}{% endblock %}
|
||||
{% block title %} {% trans "Participants" %} - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n crispy_forms_tags %}
|
||||
|
||||
{% block title %}Create Applicant - {{ block.super }}{% endblock %}
|
||||
{% block title %}{% trans "Create Applicant" %} - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Delete Person" %} - {{ block.super }}{% endblock %}
|
||||
{% block title %}{% trans "Delete Applicant" %} - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container py-4">
|
||||
@ -48,7 +48,7 @@
|
||||
<i class="fas fa-arrow-left me-1"></i> {% trans "Cancel" %}
|
||||
</a>
|
||||
<button type="submit" class="btn btn-danger">
|
||||
<i class="fas fa-trash me-1"></i> {% trans "Delete Person" %}
|
||||
<i class="fas fa-trash me-1"></i> {% trans "Delete Applicant" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}People - {{ block.super }}{% endblock %}
|
||||
{% block title %}{% trans "Applicants" %} - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
@ -383,10 +383,10 @@
|
||||
<div class="card-body">
|
||||
<i class="fas fa-user-friends fa-3x mb-3" style="color: var(--kaauh-teal-dark);"></i>
|
||||
<h3>{% trans "No people found" %}</h3>
|
||||
<p class="text-muted">{% trans "Create your first person record." %}</p>
|
||||
<p class="text-muted">{% trans "Create your first applicant record." %}</p>
|
||||
{% if user.is_staff %}
|
||||
<a href="{% url 'person_create' %}" class="btn btn-main-action mt-3">
|
||||
<i class="fas fa-plus me-1"></i> {% trans "Add Person" %}
|
||||
<i class="fas fa-plus me-1"></i> {% trans "Add Applicant" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n crispy_forms_tags %}
|
||||
|
||||
{% block title %}Update {{ person.get_full_name }} - {{ block.super }}{% endblock %}
|
||||
{% block title %}{% trans "Update" %} {{ person.get_full_name }} - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -8,6 +8,11 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="{% trans 'King Abdullah Academic University Hospital - Agency Portal' %}">
|
||||
<title>{% block title %}{% trans 'KAAUH Agency Portal' %}{% endblock %}</title>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'image/favicon/apple-touch-icon.png'%}">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{% static 'image/favicon/favicon-32x32.png'%}">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'image/favicon/favicon-16x16.png'%}">
|
||||
<link rel="manifest" href="{% static 'image/favicon/site.webmanifest'%}">
|
||||
|
||||
|
||||
{# Load correct Bootstrap CSS file for RTL/LTR #}
|
||||
{% if LANGUAGE_CODE == 'ar' %}
|
||||
|
||||
@ -22,16 +22,16 @@
|
||||
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<div class="me-3">
|
||||
<strong>Agency:</strong> {{ access_link.assignment.agency.name }}
|
||||
<strong>{% trans "Agency:" %}</strong> {{ access_link.assignment.agency.name }}
|
||||
</div>
|
||||
<div class="me-3">
|
||||
<strong>Job:</strong> {{ access_link.assignment.job.title }}
|
||||
<strong>{% trans "Job:" %}</strong> {{ access_link.assignment.job.title }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<div class="me-3">
|
||||
<strong>Current Status:</strong>
|
||||
<strong>{% trans "Current Status:" %}</strong>
|
||||
<span class="badge bg-{{ 'success' if access_link.is_active else 'danger' }}">
|
||||
{{ 'Active' if access_link.is_active else 'Inactive' }}
|
||||
</span>
|
||||
@ -40,23 +40,23 @@
|
||||
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<div class="me-3">
|
||||
<strong>Expires:</strong> {{ access_link.expires_at|date:"Y-m-d H:i" }}
|
||||
<strong>{% trans "Expires:" %}</strong> {{ access_link.expires_at|date:"Y-m-d H:i" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<div class="me-3">
|
||||
<strong>Access Count:</strong> {{ access_link.access_count }}
|
||||
<strong>{% trans "Access Count:" %}</strong> {{ access_link.access_count }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<div class="me-3">
|
||||
<strong>Last Accessed:</strong>
|
||||
<strong>{% trans "Last Accessed:" %}</strong>
|
||||
{% if access_link.last_accessed %}
|
||||
{{ access_link.last_accessed|date:"Y-m-d H:i" }}
|
||||
{% else %}
|
||||
Never
|
||||
{% trans "Never" %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@ -66,7 +66,7 @@
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
|
||||
<a href="{{ cancel_url }}" class="btn btn-secondary">
|
||||
<i class="fas fa-times me-2"></i>
|
||||
Cancel
|
||||
{% trans "Cancel" %}
|
||||
</a>
|
||||
<button type="submit" class="btn btn-warning">
|
||||
<i class="fas fa-{{ 'toggle-on' if title == 'Reactivate Access Link' else 'toggle-off' }} me-2"></i>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'portal_base.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{{ assignment.job.title }} - {{ assignment.agency.name }} - Agency Portal{% endblock %}
|
||||
{% block title %}{{ assignment.job.title }} - {{ assignment.agency.name }} - {% trans "Agency Portal" %}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'portal_base.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Agency Dashboard" %} - ATS{% endblock %}
|
||||
{% block title %}{% trans "Agency Dashboard" %} -{% trans "Aagency Portal" %}{% endblock %}
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
:root {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'portal_base.html' %}
|
||||
{% load static i18n crispy_forms_tags %}
|
||||
|
||||
{% block title %}{% trans "Persons List" %} - ATS{% endblock %}
|
||||
{% block title %}{% trans "Agency Applicant List" %} - ATS{% endblock %}
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
:root {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'portal_base.html' %}
|
||||
{% load static i18n crispy_forms_tags %}
|
||||
|
||||
{% block title %}{% trans "Submit Application" %} - {{ assignment.job.title }} - Agency Portal{% endblock %}
|
||||
{% block title %}{% trans "Submit Application" %} - {{ assignment.job.title }} - {% trans "Agency Portal" %}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -292,7 +292,7 @@
|
||||
{# Header: Larger, more dynamic on large screens. Stacks cleanly on mobile. #}
|
||||
<div class="d-flex flex-column flex-md-row justify-content-between align-items-md-center mb-5">
|
||||
<h1 class="display-6 display-md-5 fw-extrabold mb-3 mb-md-0" style="color: var(--kaauh-teal-dark);">
|
||||
{% trans "Your Applicant Dashboard" %}
|
||||
{% trans "Dashboard" %}
|
||||
</h1>
|
||||
{% comment %} <a href="#profile-details" data-bs-toggle="tab" class="btn btn-main-action btn-sm btn-md-lg px-4 py-2 rounded-pill shadow-sm shadow-md-lg">
|
||||
<i class="fas fa-edit me-2"></i> {% trans "Update Profile" %}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n crispy_forms_tags %}
|
||||
|
||||
{% block title %}Create Application - {{ block.super }}{% endblock %}
|
||||
{% block title %}{% trans "Create Application" %} - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
{% if LANGUAGE_CODE == 'ar' %}
|
||||
<title>{{ application.resume_data_ar.full_name|default:"Application" }} - Application Profile</title>
|
||||
{% else %}
|
||||
<title>{{ application.resume_data_en.full_name|default:"Application" }} - Application Profile</title>
|
||||
<title>{{ application.resume_data_en.full_name|default:"Application" }} - {% trans "Application Profile" %}</title>
|
||||
{% endif %}
|
||||
<!-- Use a modern icon set -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n crispy_forms_tags %}
|
||||
|
||||
{% block title %}Update {{ object.name }} - {{ block.super }}{% endblock %}
|
||||
{% block title %}{% trans "Update" %} {{ object.name }} - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% blocktrans %} Document Review - {{ job.title }} - University ATS{%endblocktrans %}{% endblock %}
|
||||
{% block title %}{% blocktrans %} Document Review Stage - {{ job.title }} - University ATS{%endblocktrans %}{% endblock %}
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
/* KAAT-S UI Variables */
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% blocktrans %}Application Tier Management - {{ job.title }} - ATS {% endblocktrans %}{% endblock %}
|
||||
{% block title %}{% blocktrans %}Exam Stage- {{ job.title }} - ATS {% endblocktrans %}{% endblock %}
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
/* KAAT-S UI Variables */
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}- {{ job.title }} - ATS{% endblock %}
|
||||
{% block title %}{% trans "Hired Stage" %} {{ job.title }} - ATS{% endblock %}
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
/* KAAT-S UI Variables */
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% blocktrans %}Application Tier Management - {{ job.title }} - ATS {% endblocktrans %}{% endblock %}
|
||||
{% block title %}{% blocktrans %}Interview Stage - {{ job.title }} - ATS {% endblocktrans %}{% endblock %}
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
/* KAAT-S UI Variables */
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}Applications - {{ block.super }}{% endblock %}
|
||||
{% block title %}{% trans "Applications" %} - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static i18n %}
|
||||
{% block title %}{% blocktrans %}Application Tier Management - {{ job.title }} - ATS {% endblocktrans %}{% endblock %}
|
||||
{% block title %}{% blocktrans %}Offer Stage - {{ job.title }} - ATS {% endblocktrans %}{% endblock %}
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
/* KAAT-S UI Variables */
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}Application Management - {{ job.title }} - University ATS{% endblock %}
|
||||
{% block title %} {% blocktrans %} Screening Stage - {{ job.title }} - University ATS{% endblocktrans %}{% endblock %}
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
/* KAAT-S UI Variables */
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Delete Candidate" %} - {{ block.super }}{% endblock %}
|
||||
{% block title %}{% trans "Delete Applicant" %} - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
@ -176,14 +176,14 @@
|
||||
<div>
|
||||
<h1 class="h3 mb-1" style="color: var(--kaauh-teal-dark); font-weight: 700;">
|
||||
<i class="fas fa-exclamation-triangle me-2"></i>
|
||||
{% trans "Delete Candidate" %}
|
||||
{% trans "Delete Applicant" %}
|
||||
</h1>
|
||||
<p class="text-muted mb-0">
|
||||
{% trans "You are about to delete a candidate application. This action cannot be undone." %}
|
||||
{% trans "You are about to delete an applicant's application. This action cannot be undone." %}
|
||||
</p>
|
||||
</div>
|
||||
<a href="{% url 'candidate_detail' object.slug %}" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left me-1"></i> {% trans "Back to Candidate" %}
|
||||
<i class="fas fa-arrow-left me-1"></i> {% trans "Back to Applicant" %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -196,7 +196,7 @@
|
||||
</div>
|
||||
<h3 class="warning-title">{% trans "Warning: This action cannot be undone!" %}</h3>
|
||||
<p class="warning-text">
|
||||
{% trans "Deleting this candidate will permanently remove all associated data. Please review the information below carefully before proceeding." %}
|
||||
{% trans "Deleting this applicant will permanently remove all associated data. Please review the information below carefully before proceeding." %}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -205,7 +205,7 @@
|
||||
<div class="card-header bg-white border-bottom">
|
||||
<h5 class="mb-0" style="color: var(--kaauh-teal-dark);">
|
||||
<i class="fas fa-user me-2"></i>
|
||||
{% trans "Candidate to be Deleted" %}
|
||||
{% trans "Applicant to be Deleted" %}
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@ -288,14 +288,14 @@
|
||||
<div class="card-header bg-white border-bottom">
|
||||
<h5 class="mb-0" style="color: var(--kaauh-teal-dark);">
|
||||
<i class="fas fa-list me-2"></i>
|
||||
{% trans "What will happen when you delete this candidate?" %}
|
||||
{% trans "What will happen when you delete this applicant?" %}
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ul class="consequence-list">
|
||||
<li>
|
||||
<i class="fas fa-times-circle"></i>
|
||||
{% trans "The candidate profile and all personal information will be permanently deleted" %}
|
||||
{% trans "The applicant profile and all personal information will be permanently deleted" %}
|
||||
</li>
|
||||
<li>
|
||||
<i class="fas fa-times-circle"></i>
|
||||
@ -327,7 +327,7 @@
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="confirm_delete" name="confirm_delete" required>
|
||||
<label class="form-check-label" for="confirm_delete">
|
||||
<strong>{% trans "I understand that this action cannot be undone and I want to permanently delete this candidate." %}</strong>
|
||||
<strong>{% trans "I understand that this action cannot be undone and I want to permanently delete this applicant." %}</strong>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@ -342,7 +342,7 @@
|
||||
id="deleteButton"
|
||||
disabled>
|
||||
<i class="fas fa-trash me-2"></i>
|
||||
{% trans "Delete Candidate Permanently" %}
|
||||
{% trans "Delete Applicant Permanently" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
{% extends "portal_base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}Document Management{% endblock %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Document Management" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-2xl font-bold text-gray-900">Document Management</h1>
|
||||
<h1 class="text-2xl font-bold text-gray-900">{% trans "Document Management" %}</h1>
|
||||
<button onclick="showUploadModal()" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg font-medium transition-colors">
|
||||
<i class="fas fa-upload mr-2"></i>
|
||||
Upload Document
|
||||
{% trans "Upload Document" %}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -21,22 +21,22 @@
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
Document Type
|
||||
{% trans "Document Type" %}
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
Description
|
||||
{% trans "Description" %}
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
File Name
|
||||
{% trans "File Name" %}
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
Size
|
||||
{% trans "Size" %}
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
Uploaded
|
||||
{% trans "Uploaded" %}
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
Actions
|
||||
{% trans "Actions" %}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -88,7 +88,7 @@
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="6" class="px-6 py-4 text-center text-gray-500">
|
||||
No documents uploaded yet.
|
||||
{% trans "No documents uploaded yet." %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@ -105,7 +105,7 @@
|
||||
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
||||
<div class="flex justify-between items-start mb-4">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Upload New Document
|
||||
{% trans "Upload New Document" %}
|
||||
</h3>
|
||||
<button onclick="hideUploadModal()" class="text-gray-400 hover:text-gray-600">
|
||||
<i class="fas fa-times"></i>
|
||||
@ -115,26 +115,26 @@
|
||||
{% csrf_token %}
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<label for="document_type" class="block text-sm font-medium text-gray-700">Document Type</label>
|
||||
<label for="document_type" class="block text-sm font-medium text-gray-700">{% trans "Document Type" %}</label>
|
||||
<select id="document_type" name="document_type" required
|
||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
|
||||
<option value="resume">Resume</option>
|
||||
<option value="cover_letter">Cover Letter</option>
|
||||
<option value="transcript">Transcript</option>
|
||||
<option value="certificate">Certificate</option>
|
||||
<option value="id_document">ID Document</option>
|
||||
<option value="portfolio">Portfolio</option>
|
||||
<option value="other">Other</option>
|
||||
<option value="resume">{% trans "Resume" %}</option>
|
||||
<option value="cover_letter">{% trans "Cover Letter" %}</option>
|
||||
<option value="transcript">{% trans "Transcript" %}</option>
|
||||
<option value="certificate">{% trans "Certificate" %}</option>
|
||||
<option value="id_document">{% trans "ID Document" %}</option>
|
||||
<option value="portfolio">{% trans "Portfolio" %}</option>
|
||||
<option value="other">{% trans "Other" %}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="description" class="block text-sm font-medium text-gray-700">Description</label>
|
||||
<label for="description" class="block text-sm font-medium text-gray-700">{% trans "Description" %}</label>
|
||||
<textarea id="description" name="description" rows="3"
|
||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||
placeholder="Optional description of the document"></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label for="file" class="block text-sm font-medium text-gray-700">File</label>
|
||||
<label for="file" class="block text-sm font-medium text-gray-700">{% trans "File" %}</label>
|
||||
<input type="file" id="file" name="file" required
|
||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||
accept=".pdf,.doc,.docx,.txt,.jpg,.jpeg,.png">
|
||||
@ -143,11 +143,11 @@
|
||||
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
||||
<button type="button" onclick="hideUploadModal()"
|
||||
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
Cancel
|
||||
{% trans "Cancel" %}
|
||||
</button>
|
||||
<button type="submit"
|
||||
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
|
||||
Upload Document
|
||||
{% trans "Upload Document" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@ -167,7 +167,7 @@ function hideUploadModal() {
|
||||
}
|
||||
|
||||
function deleteDocument(documentId) {
|
||||
if (confirm('Are you sure you want to delete this document?')) {
|
||||
if (confirm('{% trans "Are you sure you want to delete this document?" %}')) {
|
||||
fetch(`/candidate/documents/${documentId}/delete/`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@ -184,14 +184,14 @@ function deleteDocument(documentId) {
|
||||
row.remove();
|
||||
|
||||
// Show success message
|
||||
showNotification('Document deleted successfully!', 'success');
|
||||
showNotification('{% trans "Document deleted successfully!" %}', 'success');
|
||||
} else {
|
||||
showNotification(data.error || 'Failed to delete document', 'error');
|
||||
showNotification(data.error || '{% trans "Failed to delete document" %}', 'error');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
showNotification('An error occurred while deleting the document', 'error');
|
||||
showNotification('{% trans "An error occurred while deleting the document" %}', 'error');
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -217,12 +217,12 @@ document.getElementById('uploadForm').addEventListener('submit', function(e) {
|
||||
// Reload the page to show the new document
|
||||
window.location.reload();
|
||||
} else {
|
||||
showNotification(data.error || 'Failed to upload document', 'error');
|
||||
showNotification(data.error || '{% trans "Failed to upload document" %}', 'error');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
showNotification('An error occurred while uploading the document', 'error');
|
||||
showNotification('{% trans "An error occurred while uploading the document" %}', 'error');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'portal_base.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Candidate Dashboard" %} - ATS{% endblock %}
|
||||
{% block title %}{% trans "Applicant Dashboard" %} - ATS{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid">
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<!-- templates/recruitment/interview_calendar.html -->
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% load static i18n %}
|
||||
{% block title %} {% trans "Interview Calendar" %} {% endblock %}
|
||||
{% block customCSS %}
|
||||
<link href="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/main.min.css" rel="stylesheet">
|
||||
<style>
|
||||
@ -115,7 +115,7 @@
|
||||
<div class="container mt-4">
|
||||
<div class="calendar-header">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h1 class="h3 mb-0">Interview Calendar</h1>
|
||||
<h1 class="h3 mb-0">{% trans "Interview Calendar" %}</h1>
|
||||
<div>
|
||||
<span class="h5">{{ job.title }}</span>
|
||||
</div>
|
||||
@ -128,19 +128,19 @@
|
||||
<div class="calendar-legend">
|
||||
<div class="legend-item">
|
||||
<div class="legend-color" style="background-color: #00636e;"></div>
|
||||
<span>Scheduled</span>
|
||||
<span>{% trans "Scheduled" %}</span>
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-color" style="background-color: #00a86b;"></div>
|
||||
<span>Confirmed</span>
|
||||
<span>{% trans "Confirmed" %}</span>
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-color" style="background-color: #e74c3c;"></div>
|
||||
<span>Cancelled</span>
|
||||
<span>{% trans "Cancelled" %}</span>
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-color" style="background-color: #95a5a6;"></div>
|
||||
<span>Completed</span>
|
||||
<span>{% trans "Completed" %}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -148,7 +148,7 @@
|
||||
<div class="interview-details" id="interview-details" style="display: none;">
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0">Interview Details</h5>
|
||||
<h5 class="mb-0">{% trans "Interview Details" %}</h5>
|
||||
<button type="button" class="btn-close" id="close-details"></button>
|
||||
</div>
|
||||
<div class="card-body" id="interview-info">
|
||||
@ -209,9 +209,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
if (event.extendedProps.meeting_id) {
|
||||
meetingInfo = `
|
||||
<div class="mb-3">
|
||||
<h6>Meeting Information</h6>
|
||||
<p><strong>Meeting ID:</strong> ${event.extendedProps.meeting_id}</p>
|
||||
<p><strong>Join URL:</strong> <a href="${event.extendedProps.join_url}" target="_blank">${event.extendedProps.join_url}</a></p>
|
||||
<h6>{ % tran "Meeting Information" %}</h6>
|
||||
<p><strong>{ % tran "Meeting ID:" %}</strong> ${event.extendedProps.meeting_id}</p>
|
||||
<p><strong>{ % tran "Join URL:" %}</strong> <a href="${event.extendedProps.join_url}" target="_blank">${event.extendedProps.join_url}</a></p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@ -219,20 +219,20 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
infoContainer.innerHTML = `
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h6>Candidate Information</h6>
|
||||
<p><strong>Name:</strong> ${event.extendedProps.candidate}</p>
|
||||
<p><strong>Email:</strong> ${event.extendedProps.email}</p>
|
||||
<h6>{% trans "Candidate Information" %}</h6>
|
||||
<p><strong>{% trans "Name:" %}</strong> ${event.extendedProps.candidate}</p>
|
||||
<p><strong>{% trans "Email:" %}</strong> ${event.extendedProps.email}</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h6>Interview Details</h6>
|
||||
<p><strong>Date:</strong> ${event.start.toLocaleDateString()}</p>
|
||||
<p><strong>Time:</strong> ${event.start.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})} - ${event.end.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}</p>
|
||||
<p><strong>Status:</strong> <span class="status-badge ${statusClass}">${statusText}</span></p>
|
||||
<h6>{% trans "Interview Details" %}</h6>
|
||||
<p><strong>{% trans "Date:" %}</strong> ${event.start.toLocaleDateString()}</p>
|
||||
<p><strong>{% trans "Time:" %}</strong> ${event.start.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})} - ${event.end.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}</p>
|
||||
<p><strong>{% trans "Status:" %}</strong> <span class="status-badge ${statusClass}">${statusText}</span></p>
|
||||
</div>
|
||||
</div>
|
||||
${meetingInfo}
|
||||
<div class="mt-3">
|
||||
<a href="${event.url}" class="btn btn-primary btn-sm">View Full Details</a>
|
||||
<a href="${event.url}" class="btn btn-primary btn-sm">{% trans "View Full Details" %}</a>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<!-- templates/recruitment/interview_detail.html -->
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block extra_css %}
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
:root {
|
||||
--calendar-color: #00636e;
|
||||
@ -52,7 +52,7 @@
|
||||
<div class="container mt-4">
|
||||
<div class="detail-header">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h1 class="h3 mb-0">Interview Details</h1>
|
||||
<h1 class="h3 mb-0">{% trans "Interview Details" %}</h1>
|
||||
<div>
|
||||
<span class="h5">{{ job.title }}</span>
|
||||
</div>
|
||||
@ -63,35 +63,35 @@
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h5>Candidate Information</h5>
|
||||
<h5>{% trans "Applicant Information"%}</h5>
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td><strong>Name:</strong></td>
|
||||
<td><strong>{% trans "Name:" %}</strong></td>
|
||||
<td>{{ interview.candidate.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Email:</strong></td>
|
||||
<td><strong>{% trans "Email:" %}</strong></td>
|
||||
<td>{{ interview.candidate.email }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Phone:</strong></td>
|
||||
<td><strong>{% trans "Phone:" %}</strong></td>
|
||||
<td>{{ interview.candidate.phone|default:"Not provided" }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h5>Interview Details</h5>
|
||||
<h5>{% trans "Interview Details" %}</h5>
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td><strong>Date:</strong></td>
|
||||
<td><strong>{% trans "Date:" %}</strong></td>
|
||||
<td>{{ interview.interview_date|date:"l, F j, Y" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Time:</strong></td>
|
||||
<td><strong>{% trans "Time:" %}</strong></td>
|
||||
<td>{{ interview.interview_time|time:"g:i A" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Status:</strong></td>
|
||||
<td><strong>{% trans "Status:" %}</strong></td>
|
||||
<td>
|
||||
<span class="status-badge status-{{ interview.status }}">
|
||||
{{ interview.status|title }}
|
||||
@ -104,22 +104,22 @@
|
||||
|
||||
{% if interview.zoom_meeting %}
|
||||
<div class="mt-4">
|
||||
<h5>Meeting Information</h5>
|
||||
<h5>{% trans "Meeting Information" %}</h5>
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td><strong>Meeting ID:</strong></td>
|
||||
<td><strong>{% trans "Meeting ID:" %}</strong></td>
|
||||
<td>{{ interview.zoom_meeting.meeting_id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Topic:</strong></td>
|
||||
<td><strong>{% trans "Topic:" %}</strong></td>
|
||||
<td>{{ interview.zoom_meeting.topic }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Duration:</strong></td>
|
||||
<td>{{ interview.zoom_meeting.duration }} minutes</td>
|
||||
<td><strong>{% trans "Duration:" %}</strong></td>
|
||||
<td>{{ interview.zoom_meeting.duration }} {% trans "minutes" %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Join URL:</strong></td>
|
||||
<td><strong>{% trans "Join URL:" %}</strong></td>
|
||||
<td><a href="{{ interview.zoom_meeting.join_url }}" target="_blank">{{ interview.zoom_meeting.join_url }}</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -129,16 +129,16 @@
|
||||
<div class="mt-4">
|
||||
<div class="d-flex gap-2">
|
||||
<a href="{% url 'interview_calendar' slug=job.slug %}" class="btn btn-secondary">
|
||||
<i class="fas fa-calendar"></i> Back to Calendar
|
||||
<i class="fas fa-calendar"></i> {% trans "Back to Calendar" %}
|
||||
</a>
|
||||
{% if interview.status == 'scheduled' %}
|
||||
<button class="btn btn-success">
|
||||
<i class="fas fa-check"></i> Confirm Interview
|
||||
<i class="fas fa-check"></i> {% trans "Confirm Interview" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
{% if interview.status != 'cancelled' and interview.status != 'completed' %}
|
||||
<button class="btn btn-danger">
|
||||
<i class="fas fa-times"></i> Cancel Interview
|
||||
<i class="fas fa-times"></i> {% trans "Cancel Interview" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
{% load i18n %}
|
||||
<span id="stageDisplay" class="badge bg-{% if candidate.stage == 'Applied' %}primary{% elif candidate.stage == 'Exam' %}info{% elif candidate.stage == 'Interview' %}warning{% elif candidate.stage == 'Offer' %}success{% else %}secondary{% endif %}">
|
||||
Stage: {{ candidate.get_stage_display }}
|
||||
{% trans "Stage:" %} {{ candidate.get_stage_display }}
|
||||
</span>
|
||||
@ -1,11 +1,12 @@
|
||||
<!-- Stage Update Form with Errors -->
|
||||
{% load i18n %}
|
||||
<form id="stageUpdateForm" hx-post="{% url 'application_update_stage' candidate.slug %}">
|
||||
{% csrf_token %}
|
||||
|
||||
<!-- Stage Selection -->
|
||||
<div class="mb-3">
|
||||
<label for="id_stage" class="form-label">
|
||||
<i class="fas fa-arrow-right me-1"></i>Move to Stage
|
||||
<i class="fas fa-arrow-right me-1"></i>{% trans "Move to Stage" %}
|
||||
</label>
|
||||
<select name="stage" id="id_stage" class="form-select {% if form.stage.errors %}is-invalid{% endif %}">
|
||||
{% for value, label in form.stage.field.choices %}
|
||||
@ -30,10 +31,10 @@
|
||||
<!-- Form Actions -->
|
||||
<div class="d-flex justify-content-between mt-4">
|
||||
<button type="button" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left me-1"></i>Cancel
|
||||
<i class="fas fa-arrow-left me-1"></i>{% trans "Cancel" %}
|
||||
</button>
|
||||
<button type="submit" class="btn btn-primary" id="stageUpdateSubmit">
|
||||
<i class="fas fa-save me-1"></i>Update Stage
|
||||
<i class="fas fa-save me-1"></i>{% trans "Update Stage" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<div id="availableStagesInfo" class="alert alert-success">
|
||||
<div class="d-flex align-items-center">
|
||||
<i class="fas fa-check-circle me-2"></i>
|
||||
<strong>Success:</strong>
|
||||
<strong>{% trans "Success:" %}</strong>
|
||||
<span class="ms-2">{{ message }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
{%load i18n %}
|
||||
{% load i18n %}
|
||||
{# -------------------------------------------------------------------------- #}
|
||||
{# STATS CARDS SECTION (12 KPIs) #}
|
||||
{# -------------------------------------------------------------------------- #}
|
||||
|
||||
@ -1,17 +1,18 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
{% load widget_tweaks %}
|
||||
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid py-4">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<!-- Breadcrumb Navigation -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{% url 'settings_list' %}" class="text-decoration-none text-secondary">
|
||||
<i class="fas fa-cog me-1"></i> Settings
|
||||
<i class="fas fa-cog me-1"></i> {% trans "Settings" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item">
|
||||
@ -20,62 +21,58 @@
|
||||
</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active" aria-current="page"
|
||||
style="color: #F43B5E; font-weight: 600;">Delete</li>
|
||||
style="color: #F43B5E; font-weight: 600;">{% trans "Delete" %}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<!-- Header -->
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1 class="h3 mb-0 text-primary-theme">
|
||||
<i class="fas fa-exclamation-triangle me-2"></i>
|
||||
{{ title }}
|
||||
</h1>
|
||||
<a href="{{ cancel_url }}" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-arrow-left me-1"></i> Cancel
|
||||
<i class="fas fa-arrow-left me-1"></i> {% trans "Cancel" %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Warning Card -->
|
||||
<div class="card shadow-sm border-danger">
|
||||
<div class="card-body">
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="{% trans 'Close' %}"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Warning Alert -->
|
||||
<div class="alert alert-warning d-flex align-items-center" role="alert">
|
||||
<i class="fas fa-exclamation-triangle me-3 fa-lg"></i>
|
||||
<div>
|
||||
<strong>Warning:</strong> This action cannot be undone. Deleting this setting will permanently remove it from the system.
|
||||
<strong>{% trans "Warning:" %}</strong> {% trans "This action cannot be undone. Deleting this setting will permanently remove it from the system." %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Setting Details -->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h5 class="mb-3">Setting Details:</h5>
|
||||
<h5 class="mb-3">{% trans "Setting Details:" %}</h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th style="width: 150px;" class="text-primary-theme">Key:</th>
|
||||
<th style="width: 150px;" class="text-primary-theme">{% trans "Key:" %}</th>
|
||||
<td><code class="text-primary-theme">{{ setting.key }}</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="text-primary-theme">Value:</th>
|
||||
<th class="text-primary-theme">{% trans "Value:" %}</th>
|
||||
<td>{{ setting.value|default:"-" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="text-primary-theme">Description:</th>
|
||||
<td>{{ setting.description|default:"No description" }}</td>
|
||||
<th class="text-primary-theme">{% trans "Description:" %}</th>
|
||||
<td>{{ setting.description|default:_("No description") }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="text-primary-theme">Type:</th>
|
||||
<th class="text-primary-theme">{% trans "Type:" %}</th>
|
||||
<td>
|
||||
<span class="badge bg-primary-theme text-white">
|
||||
{{ setting.get_type_display }}
|
||||
@ -83,12 +80,12 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="text-primary-theme">Status:</th>
|
||||
<th class="text-primary-theme">{% trans "Status:" %}</th>
|
||||
<td>
|
||||
{% if setting.is_active %}
|
||||
<span class="badge bg-primary-theme text-white">Active</span>
|
||||
<span class="badge bg-primary-theme text-white">{% trans "Active" %}</span>
|
||||
{% else %}
|
||||
<span class="badge bg-secondary text-white">Inactive</span>
|
||||
<span class="badge bg-secondary text-white">{% trans "Inactive" %}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
@ -98,17 +95,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="row mt-4">
|
||||
<div class="col-12">
|
||||
<form method="post" onsubmit="return confirm('Are you absolutely sure you want to delete this setting? This action cannot be undone.');">
|
||||
<form method="post" onsubmit="return confirm('{% trans "Are you absolutely sure you want to delete this setting? This action cannot be undone." %}');">
|
||||
{% csrf_token %}
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" class="btn btn-danger">
|
||||
<i class="fas fa-trash me-1"></i> Yes, Delete Setting
|
||||
<i class="fas fa-trash me-1"></i> {% trans "Yes, Delete Setting" %}
|
||||
</button>
|
||||
<a href="{{ cancel_url }}" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-times me-1"></i> Cancel
|
||||
<i class="fas fa-times me-1"></i> {% trans "Cancel" %}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
@ -116,8 +112,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
@ -1,4 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
@ -122,7 +123,7 @@
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{% url 'settings_list' %}" class="text-decoration-none text-secondary">
|
||||
<i class="fas fa-cog me-1"></i> Settings
|
||||
<i class="fas fa-cog me-1"></i>{% trans "Settings" %}
|
||||
</a>
|
||||
</li>
|
||||
{% if setting %}
|
||||
@ -132,10 +133,10 @@
|
||||
</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active" aria-current="page"
|
||||
style="color: #F43B5E; font-weight: 600;">Update</li>
|
||||
style="color: #F43B5E; font-weight: 600;">{% trans "Update" %}</li>
|
||||
{% else %}
|
||||
<li class="breadcrumb-item active" aria-current="page"
|
||||
style="color: #F43B5E; font-weight: 600;">Create</li>
|
||||
style="color: #F43B5E; font-weight: 600;">{% trans "Create" %}</li>
|
||||
{% endif %}
|
||||
</ol>
|
||||
</nav>
|
||||
@ -148,14 +149,14 @@
|
||||
<div class="d-flex gap-2">
|
||||
{% if setting %}
|
||||
<a href="{% url 'settings_detail' setting.pk %}" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-eye me-1"></i> View Details
|
||||
<i class="fas fa-eye me-1"></i> {% trans "View Details" %}
|
||||
</a>
|
||||
<a href="{% url 'settings_delete' setting.pk %}" class="btn btn-danger">
|
||||
<i class="fas fa-trash me-1"></i> Delete
|
||||
<i class="fas fa-trash me-1"></i> {% trans "Delete" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
<a href="{% url 'settings_list' %}" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-arrow-left me-1"></i> Back to List
|
||||
<i class="fas fa-arrow-left me-1"></i> {% trans "Back to List" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -166,7 +167,7 @@
|
||||
{% if form.non_field_errors %}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<h5 class="alert-heading">
|
||||
<i class="fas fa-exclamation-triangle me-2"></i>Error
|
||||
<i class="fas fa-exclamation-triangle me-2"></i>{% trans "Error" %}
|
||||
</h5>
|
||||
{% for error in form.non_field_errors %}
|
||||
<p class="mb-0">{{ error }}</p>
|
||||
@ -191,7 +192,7 @@
|
||||
<i class="fas fa-save me-1"></i> {{ button_text }}
|
||||
</button>
|
||||
<a href="{% url 'settings_list' %}" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-times me-1"></i> Cancel
|
||||
<i class="fas fa-times me-1"></i> {% trans "Cancel" %}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h4 class="h3 mb-0">{{ title }}</h4>
|
||||
<a href="{% url 'source_detail' source.pk %}" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Back to Source
|
||||
<i class="fas fa-arrow-left"></i> {% trans "Back to Source" %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -21,40 +21,40 @@
|
||||
<div class="alert alert-warning d-flex align-items-center">
|
||||
<i class="fas fa-exclamation-triangle fa-2x me-3"></i>
|
||||
<div>
|
||||
<strong>Warning:</strong> This action cannot be undone.
|
||||
Deleting this source will also remove all associated integration logs and API credentials.
|
||||
<strong>{% trans "Warning:" %}</strong> {% trans "This action cannot be undone.
|
||||
Deleting this source will also remove all associated integration logs and API credentials." %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<h5>Source to be deleted:</h5>
|
||||
<h5>{% trans "Source to be deleted:" %}</h5>
|
||||
<div class="card bg-light">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<strong>Name:</strong><br>
|
||||
<strong>{% trans "Name:" %}</strong><br>
|
||||
{{ source.name }}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<strong>Type:</strong><br>
|
||||
<strong>{% trans "Type:" %}</strong><br>
|
||||
<span class="badge bg-info">{{ source.get_source_type_display }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{% if source.description %}
|
||||
<hr>
|
||||
<div>
|
||||
<strong>Description:</strong><br>
|
||||
<strong>{% trans "Description:" %}</strong><br>
|
||||
{{ source.description|linebreaks }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<strong>Created:</strong><br>
|
||||
<strong>{% trans "Created:" %}</strong><br>
|
||||
{{ source.created_at|date:"M d, Y H:i" }}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<strong>Total API Calls:</strong><br>
|
||||
<strong>{% trans "Total API Calls:" %}</strong><br>
|
||||
{{ source.integration_logs.count }}
|
||||
</div>
|
||||
</div>
|
||||
@ -66,10 +66,10 @@
|
||||
{% csrf_token %}
|
||||
<div class="d-flex justify-content-between">
|
||||
<a href="{{ cancel_url }}" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-times"></i> Cancel
|
||||
<i class="fas fa-times"></i> {% trans "Cancel" %}
|
||||
</a>
|
||||
<button type="submit" class="btn btn-danger">
|
||||
<i class="fas fa-trash"></i> Delete Source
|
||||
<i class="fas fa-trash"></i>{% trans "Delete Source" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@ -80,25 +80,25 @@
|
||||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h6 class="mb-0">Impact Summary</h6>
|
||||
<h6 class="mb-0">{% trans "Impact Summary" %}</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label text-muted">Integration Logs</label>
|
||||
<label class="form-label text-muted">{% trans "Integration Logs" %}</label>
|
||||
<div class="h5 mb-0 text-danger">
|
||||
{{ source.integration_logs.count }} will be deleted
|
||||
{{ source.integration_logs.count }} {% trans "will be deleted" %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label text-muted">API Credentials</label>
|
||||
<label class="form-label text-muted">{% trans "API Credentials" %}</label>
|
||||
<div class="h5 mb-0 text-danger">
|
||||
API Key & Secret will be permanently lost
|
||||
{% trans "API Key & Secret will be permanently lost" %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label text-muted">Active Integrations</label>
|
||||
<label class="form-label text-muted">{% trans "Active Integrations" %}</label>
|
||||
<div class="h5 mb-0 text-warning">
|
||||
Any systems using this API will lose access
|
||||
{% trans "Any systems using this API will lose access" %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,143 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n crispy_forms_tags %}
|
||||
|
||||
{% block title %}Create Training Material - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
|
||||
<style>
|
||||
/* ================================================= */
|
||||
/* THEME VARIABLES AND GLOBAL STYLES */
|
||||
/* (Your existing CSS is kept here) */
|
||||
/* ================================================= */
|
||||
: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; }
|
||||
|
||||
|
||||
|
||||
/* Main Action Button Style */
|
||||
.btn-main-action{
|
||||
background-color: gray; /* Changed to primary teal for main actions */
|
||||
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, .btn-primary:hover {
|
||||
background-color: var(--kaauh-teal-dark); /* Darker on hover */
|
||||
border-color: var(--kaauh-teal-dark);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
/* Outlined Button Styles */
|
||||
.btn-secondary, .btn-outline-secondary {
|
||||
background-color: #f8f9fa;
|
||||
color: var(--kaauh-teal-dark);
|
||||
border: 1px solid var(--kaauh-teal);
|
||||
font-weight: 500;
|
||||
}
|
||||
.btn-secondary:hover, .btn-outline-secondary:hover {
|
||||
background-color: var(--kaauh-teal-dark);
|
||||
color: white;
|
||||
border-color: var(--kaauh-teal-dark);
|
||||
}
|
||||
|
||||
/* Card enhancements */
|
||||
.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;
|
||||
}
|
||||
|
||||
/* Colored Header Card */
|
||||
.list-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);
|
||||
}
|
||||
.list-header-card h1 {
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
.heroicon {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
vertical-align: text-bottom;
|
||||
stroke: currentColor;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
/* ================================================= */
|
||||
/* CLEANUP: CRISPY FORMS STYLES (Kept to ensure good defaults) */
|
||||
/* ================================================= */
|
||||
.card-body .form-group .form-label {
|
||||
font-weight: 600;
|
||||
color: var(--kaauh-primary-text);
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid py-4">
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="list-header-card">
|
||||
<div class="d-flex justify-content-between align-items-start flex-wrap">
|
||||
<div class="flex-grow-1">
|
||||
<h1 class="h3 mb-1">
|
||||
<i class="fas fa-file-upload"></i>
|
||||
{% trans "Create New Training Material" %}
|
||||
</h1>
|
||||
<p class="text-white opacity-75 mb-0">{% trans "Upload a new document or guide for your team." %}</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2 mt-1">
|
||||
<a href="{% url 'training_list' %}" class="btn btn-outline-light btn-sm" title="{% trans 'Back to List' %}">
|
||||
<i class="fas fa-arrow-left"></i>
|
||||
<span class="d-none d-sm-inline">{% trans "Back to List" %}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header bg-white border-bottom">
|
||||
<h2 class="h5 mb-0 text-primary">
|
||||
<i class="fas fa-book me-1"></i>
|
||||
{% trans "Material Details" %}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<form method="post" enctype="multipart/form-data" class="row">
|
||||
{% csrf_token %}
|
||||
|
||||
{% crispy form %}
|
||||
|
||||
{# Add the main action button here for consistency #}
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@ -1,33 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}Delete Training Material - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h1>
|
||||
<svg class="heroicon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
</svg>
|
||||
Delete Training Material: {{ object.title }}
|
||||
</h1>
|
||||
<a href="{% url 'training_list' %}" class="btn btn-secondary">Back to List</a>
|
||||
</div>
|
||||
<p>Are you sure you want to delete the training material "{{ object.title }}" created on {{ object.created_at|date:"M d, Y" }}? This action cannot be undone.</p>
|
||||
{% if object.file %}
|
||||
<p><strong>File:</strong> {{ object.file.name }}</p>
|
||||
{% endif %}
|
||||
{% if object.video_link %}
|
||||
<p><strong>Video Link:</strong> {{ object.video_link }}</p>
|
||||
{% endif %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<svg class="heroicon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
</svg>
|
||||
Yes, Delete Material
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -1,285 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Training Materials" %} - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
/* UI Variables for the KAAT-S Theme (Consistent with Reference) */
|
||||
:root {
|
||||
--kaauh-teal: #00636e;
|
||||
--kaauh-teal-dark: #004a53;
|
||||
--kaauh-border: #eaeff3;
|
||||
--kaauh-primary-text: #343a40;
|
||||
--kaauh-gray-light: #f8f9fa; /* Added for hover/background consistency */
|
||||
}
|
||||
|
||||
/* Enhanced Card Styling (Consistent) */
|
||||
.card {
|
||||
border: 1px solid var(--kaauh-border);
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
background-color: white;
|
||||
}
|
||||
/* Standard card hover effect for list items */
|
||||
.card:not(.no-hover):hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 16px rgba(0,0,0,0.1);
|
||||
}
|
||||
.card.no-hover:hover {
|
||||
transform: none;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
|
||||
}
|
||||
|
||||
/* Main Action Button Style (Teal Theme) */
|
||||
.btn-main-action {
|
||||
background-color: var(--kaauh-teal);
|
||||
border-color: var(--kaauh-teal);
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
transition: all 0.2s ease;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
.btn-main-action:hover {
|
||||
background-color: var(--kaauh-teal-dark);
|
||||
border-color: var(--kaauh-teal-dark);
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
/* Secondary Button Style (For Edit/Outline - Consistent) */
|
||||
.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);
|
||||
}
|
||||
.btn-outline-primary {
|
||||
color: var(--kaauh-teal);
|
||||
border-color: var(--kaauh-teal);
|
||||
}
|
||||
.btn-outline-primary:hover {
|
||||
background-color: var(--kaauh-teal);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Training Card Specifics */
|
||||
.training-card .card-title {
|
||||
color: var(--kaauh-teal-dark);
|
||||
font-weight: 600;
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
|
||||
/* Table Styling (Consistent with Reference) */
|
||||
.table-view .table thead th {
|
||||
background-color: var(--kaauh-teal-dark); /* Dark header background */
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
border-color: var(--kaauh-border);
|
||||
text-transform: uppercase;
|
||||
font-size: 0.8rem;
|
||||
letter-spacing: 0.5px;
|
||||
padding: 1rem;
|
||||
}
|
||||
.table-view .table tbody td {
|
||||
vertical-align: middle;
|
||||
padding: 1rem;
|
||||
border-color: var(--kaauh-border);
|
||||
}
|
||||
.table-view .table tbody tr:hover {
|
||||
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 {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
/* Override for the primary text color being used for card-titles in table */
|
||||
.text-primary { color: var(--kaauh-teal) !important; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid py-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1 style="color: var(--kaauh-teal-dark); font-weight: 700;">
|
||||
<i class="fas fa-graduation-cap me-2"></i> {% trans "Training Materials" %}
|
||||
</h1>
|
||||
{% if user.is_authenticated %}
|
||||
<a href="{% url 'training_create' %}" class="btn btn-main-action">
|
||||
<i class="fas fa-plus me-1"></i> {% trans "Add New Material" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="card mb-4 shadow-sm no-hover">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<label for="search" class="form-label small text-muted">{% trans "Search by Title or Creator" %}</label>
|
||||
<div class="input-group input-group-lg mb-3">
|
||||
<form method="get" action="" class="w-100">
|
||||
{% include "includes/search_form.html" with search_query=search_query %}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 d-flex align-items-end">
|
||||
{# Additional Filters can go here if needed #}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if materials %}
|
||||
<div id="training-materials-list">
|
||||
{# View Switcher - list_id must match the container ID #}
|
||||
{% include "includes/_list_view_switcher.html" with list_id="training-materials-list" %}
|
||||
|
||||
{# Card View (Default) - Must have 'row' class for grid layout #}
|
||||
<div class="card-view active row">
|
||||
{% for material in materials %}
|
||||
<div class="col-md-6 col-lg-4 mb-4">
|
||||
<div class="card training-card h-100 shadow-sm">
|
||||
<div class="card-body d-flex flex-column">
|
||||
<div class="d-flex justify-content-between align-items-start mb-2">
|
||||
<h5 class="card-title flex-grow-1 me-3">{{ material.title }}</h5>
|
||||
</div>
|
||||
|
||||
<p class="card-text text-muted small">
|
||||
<i class="fas fa-user-edit"></i> {% trans "Created By" %}: {{ material.created_by.username|default:"Anonymous" }}<br>
|
||||
<i class="fas fa-calendar-alt"></i> {% trans "Created On" %}: {{ material.created_at|date:"M d, Y" }}
|
||||
</p>
|
||||
|
||||
<div class="mt-auto pt-2 border-top">
|
||||
<div class="d-flex gap-2">
|
||||
<a href="{% url 'training_detail' material.pk %}" class="btn btn-sm btn-main-action">
|
||||
<i class="fas fa-eye"></i> {% trans "View" %}
|
||||
</a>
|
||||
{% if user.is_authenticated and material.created_by == user %}
|
||||
<a href="{% url 'training_update' material.pk %}" class="btn btn-sm btn-outline-secondary">
|
||||
<i class="fas fa-edit"></i> {% trans "Edit" %}
|
||||
</a>
|
||||
<button type="button" class="btn btn-outline-danger btn-sm" title="{% trans 'Delete' %}"
|
||||
data-bs-toggle="modal" data-bs-target="#deleteModal" {# Assuming standard Bootstrap modal trigger #}
|
||||
data-delete-url="{% url 'training_delete' material.pk %}"
|
||||
data-item-name="{{ material.title }}">
|
||||
<i class="fas fa-trash-alt"></i>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{# Table View #}
|
||||
<div class="table-view">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" style="width: 40%;">{% trans "Title" %}</th>
|
||||
<th scope="col" style="width: 30%;">{% trans "Created By" %}</th>
|
||||
<th scope="col" style="width: 20%;">{% trans "Created" %}</th>
|
||||
<th scope="col" style="width: 10%;" class="text-end">{% trans "Actions" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for material in materials %}
|
||||
<tr>
|
||||
<td><strong class="text-primary">{{ material.title }}</strong></td>
|
||||
<td>{{ material.created_by.username|default:"Anonymous" }}</td>
|
||||
<td>{{ material.created_at|date:"M d, Y" }}</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<a href="{% url 'training_detail' material.pk %}" class="btn btn-outline-primary" title="{% trans 'View' %}">
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
{% if user.is_authenticated and material.created_by == user %}
|
||||
<a href="{% url 'training_update' material.pk %}" class="btn btn-outline-secondary" title="{% trans 'Edit' %}">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<button type="button" class="btn btn-outline-danger" title="{% trans 'Delete' %}"
|
||||
data-bs-toggle="modal" data-bs-target="#deleteModal"
|
||||
data-delete-url="{% url 'training_delete' material.pk %}"
|
||||
data-item-name="{{ material.title }}">
|
||||
<i class="fas fa-trash-alt"></i>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Pagination (Standardized to Reference) #}
|
||||
{% if is_paginated %}
|
||||
<nav aria-label="Page navigation" class="mt-4">
|
||||
<ul class="pagination justify-content-center">
|
||||
{% if page_obj.has_previous %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page=1{% if search_query %}&q={{ search_query }}{% endif %}">First</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if search_query %}&q={{ search_query }}{% endif %}">Previous</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
<li class="page-item active">
|
||||
<span class="page-link">{{ page_obj.number }} of {{ page_obj.paginator.num_pages }}</span>
|
||||
</li>
|
||||
|
||||
{% 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 %}">Next</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}{% if search_query %}&q={{ search_query }}{% endif %}">Last</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="text-center py-5 card shadow-sm">
|
||||
<div class="card-body">
|
||||
<i class="fas fa-graduation-cap fa-3x mb-3" style="color: var(--kaauh-teal-dark);"></i>
|
||||
<h3>{% trans "No training materials found" %}</h3>
|
||||
<p class="text-muted">{% trans "It looks like there are no materials yet. Start by adding one!" %}</p>
|
||||
{% if user.is_authenticated %}
|
||||
<a href="{% url 'training_create' %}" class="btn btn-main-action mt-3">
|
||||
<i class="fas fa-plus me-1"></i> {% trans "Create Your First Material" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -1,191 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static i18n crispy_forms_tags %}
|
||||
|
||||
{% block title %}Update Training Material - {{ block.super }}{% endblock %}
|
||||
|
||||
{% block customCSS %}
|
||||
<style>
|
||||
/* ================================================= */
|
||||
/* 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; }
|
||||
|
||||
/* Main Action Button Style */
|
||||
.btn-main-action, .btn-primary {
|
||||
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, .btn-primary: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-secondary, .btn-outline-secondary {
|
||||
background-color: #f8f9fa;
|
||||
color: var(--kaauh-teal-dark);
|
||||
border: 1px solid var(--kaauh-teal);
|
||||
font-weight: 500;
|
||||
}
|
||||
.btn-secondary:hover, .btn-outline-secondary:hover {
|
||||
background-color: var(--kaauh-teal-dark);
|
||||
color: white;
|
||||
border-color: var(--kaauh-teal-dark);
|
||||
}
|
||||
|
||||
/* Card enhancements */
|
||||
.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;
|
||||
}
|
||||
|
||||
/* Colored Header Card */
|
||||
.list-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);
|
||||
}
|
||||
.list-header-card h1 {
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
.heroicon {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
vertical-align: text-bottom;
|
||||
stroke: currentColor;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
/* Form Fixes for consistency with manual rendering */
|
||||
.form-label {
|
||||
font-weight: 600;
|
||||
color: var(--kaauh-primary-text);
|
||||
margin-bottom: 0.3rem; /* Small space under label */
|
||||
display: block; /* Ensure full width for label */
|
||||
}
|
||||
|
||||
/* Ensure form fields use Bootstrap's standard look */
|
||||
.form-control {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid py-4">
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="list-header-card">
|
||||
<div class="d-flex justify-content-between align-items-start flex-wrap">
|
||||
<div class="flex-grow-1">
|
||||
<h1 class="h3 mb-1">
|
||||
<i class="fas fa-edit"></i>
|
||||
{% trans "Update Training Material:" %} {{ object.title }}
|
||||
</h1>
|
||||
<p class="text-white opacity-75 mb-0">{% trans "Edit the details of this training document or guide." %}</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2 mt-1">
|
||||
<a href="{% url 'training_list' %}" class="btn btn-outline-light btn-sm" title="{% trans 'Back to List' %}">
|
||||
<i class="fas fa-arrow-left"></i>
|
||||
<span class="d-none d-sm-inline">{% trans "Back to List" %}</span>
|
||||
</a>
|
||||
{% if object.pk %}
|
||||
<a href="{% url 'training_detail' object.pk %}" class="btn btn-outline-light btn-sm" title="{% trans 'View Material' %}">
|
||||
<i class="fas fa-eye"></i>
|
||||
<span class="d-none d-sm-inline">{% trans "View" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header bg-white border-bottom">
|
||||
<h2 class="h5 mb-0 text-primary">
|
||||
<i class="fas fa-file-alt me-1"></i>
|
||||
{% trans "Material Details" %}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<div class="card-body">
|
||||
|
||||
<div class="row g-4">
|
||||
|
||||
{# Title and Video Link on a single row #}
|
||||
<div class="col-md-6">
|
||||
<div class="mb-0">
|
||||
<label for="{{ form.title.id_for_label }}" class="form-label">{% trans "Title" %}</label>
|
||||
{{ form.title|attr:"class:form-control" }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="mb-0">
|
||||
<label for="{{ form.video_link.id_for_label }}" class="form-label">{% trans "Video Link" %}</label>
|
||||
{{ form.video_link|attr:"class:form-control" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Content (Full width) #}
|
||||
<div class="col-12">
|
||||
<div class="mb-0">
|
||||
<label for="{{ form.content.id_for_label }}" class="form-label">{% trans "Content" %}</label>
|
||||
{{ form.content|attr:"class:form-control"|attr:"rows:6" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# File Upload (Full width as it's often complex) #}
|
||||
<div class="col-12">
|
||||
<div class="mb-0">
|
||||
<label for="{{ form.file.id_for_label }}" class="form-label">{% trans "File" %}</label>
|
||||
{{ form.file }}
|
||||
{% if form.file.help_text %}
|
||||
<div class="form-text">{{ form.file.help_text }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-footer bg-light border-top">
|
||||
<div class="d-flex justify-content-end gap-3">
|
||||
<button type="submit" class="btn btn-main-action">
|
||||
<i class="fas fa-save me-1"></i>
|
||||
{% trans "Update Material" %}
|
||||
</button>
|
||||
<a href="{% url 'training_delete' object.pk %}" class="btn btn-danger" onclick="return confirm('{% trans "Are you sure you want to delete this material?" %}')">
|
||||
<i class="fas fa-trash-alt me-1"></i>
|
||||
{% trans "Delete" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -180,7 +180,7 @@
|
||||
<div class="mb-3">
|
||||
<div class="info-label">{% trans "Last Login" %}</div>
|
||||
<div class="info-value">
|
||||
{% if user.last_login %}{{ user.last_login|date:"F d, Y P" }}{% else %}N/A{% endif %}
|
||||
{% if user.last_login %}{{ user.last_login|date:"F d, Y P" }}{% else %}{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -221,7 +221,7 @@
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myModalLabel">Upload Profile image</h5>
|
||||
<h5 class="modal-title" id="myModalLabel">{% trans "Upload Profile image" %}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@ -229,17 +229,17 @@
|
||||
{% csrf_token %}
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="{{ profile_form.profile_image.id_for_label }}" class="form-label">Profile Image</label>
|
||||
<label for="{{ profile_form.profile_image.id_for_label }}" class="form-label">{% trans "Profile Image" %}</label>
|
||||
|
||||
{# 1. Check if an image currently exists on the bound instance #}
|
||||
{% if profile_form.instance.profile_image %}
|
||||
|
||||
<div class="mb-2">
|
||||
<small class="text-muted d-block">Current Image:</small>
|
||||
<small class="text-muted d-block">{% trans "Current Image:" %}</small>
|
||||
|
||||
{# Display Link to View Current Image #}
|
||||
<a href="{{ profile_form.instance.profile_image.url }}" target="_blank" class="d-inline-block me-3 text-info fw-bold">
|
||||
View/Download ({{ profile_form.instance.profile_image.name }})
|
||||
{% trans "View/Download" %} ({{ profile_form.instance.profile_image.name }})
|
||||
</a>
|
||||
|
||||
{# Image Preview #}
|
||||
@ -271,8 +271,8 @@
|
||||
</div>
|
||||
|
||||
<div class="modal-footer mt-4">
|
||||
<button type="button" class="btn btn-lg btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="submit" class="btn btn-primary">Save changes</button>
|
||||
<button type="button" class="btn btn-lg btn-secondary" data-bs-dismiss="modal">{% trans "Close" %}</button>
|
||||
<button type="submit" class="btn btn-primary">{% trans "Save changes" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -206,7 +206,7 @@
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myModalLabel">Upload Profile image</h5>
|
||||
<h5 class="modal-title" id="myModalLabel">{% trans "Upload Profile image" %}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@ -214,17 +214,17 @@
|
||||
{% csrf_token %}
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="{{ profile_form.profile_image.id_for_label }}" class="form-label">Profile Image</label>
|
||||
<label for="{{ profile_form.profile_image.id_for_label }}" class="form-label">{% trans "Profile Image" %}</label>
|
||||
|
||||
{# 1. Check if an image currently exists on the bound instance #}
|
||||
{% if profile_form.instance.profile_image %}
|
||||
|
||||
<div class="mb-2">
|
||||
<small class="text-muted d-block">Current Image:</small>
|
||||
<small class="text-muted d-block">{% trans "Current Image:" %}</small>
|
||||
|
||||
{# Display Link to View Current Image #}
|
||||
<a href="{{ profile_form.instance.profile_image.url }}" target="_blank" class="d-inline-block me-3 text-info fw-bold">
|
||||
View/Download ({{ profile_form.instance.profile_image.name }})
|
||||
{% trans "View/Download" %} ({{ profile_form.instance.profile_image.name }})
|
||||
</a>
|
||||
|
||||
{# Image Preview #}
|
||||
@ -256,8 +256,8 @@
|
||||
</div>
|
||||
|
||||
<div class="modal-footer mt-4">
|
||||
<button type="button" class="btn btn-lg btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="submit" class="btn btn-primary">Save changes</button>
|
||||
<button type="button" class="btn btn-lg btn-secondary" data-bs-dismiss="modal">{% trans "Close" %}</button>
|
||||
<button type="submit" class="btn btn-primary">{% trans "Save changes" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -215,7 +215,7 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 mb-4">
|
||||
{% comment %} <div class="col-md-4 mb-4">
|
||||
<a href="{% url 'job_bank' %}" class="text-decoration-none">
|
||||
<div class="kaauh-card shadow-sm p-4 h-100" style="border-left: 5px solid var(--kaauh-teal);">
|
||||
<div class="d-flex align-items-center">
|
||||
@ -236,7 +236,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div> {% endcomment %}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
Loading…
x
Reference in New Issue
Block a user