376 lines
22 KiB
HTML
376 lines
22 KiB
HTML
{% extends 'portal_base.html' %}
|
|
{% load static i18n mytags crispy_forms_tags %}
|
|
|
|
{% block title %}{% trans "My Dashboard" %} - ATS{% endblock %}
|
|
|
|
{% block customCSS %}
|
|
<style>
|
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap');
|
|
body { font-family: 'Inter', sans-serif; }
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="px-4 py-6">
|
|
|
|
{# Header #}
|
|
<div class="flex flex-col md:flex-row md:items-center md:justify-between mb-6">
|
|
<h1 class="text-2xl md:text-3xl font-bold text-gray-900 mb-3 md:mb-0">
|
|
{% trans "Dashboard" %}
|
|
</h1>
|
|
</div>
|
|
|
|
{# Applicant Quick Overview Card #}
|
|
<div class="bg-white rounded-2xl shadow-sm border border-gray-100 p-6 mb-6">
|
|
<div class="flex flex-col sm:flex-row items-center text-center sm:text-start gap-4">
|
|
<img src="{% if applicant.user.profile_image %}{{ applicant.user.profile_image.url }}{% else %}{% static 'image/default_avatar.png' %}{% endif %}"
|
|
alt="{% trans 'Profile Picture' %}"
|
|
class="w-20 h-20 rounded-full border-4 border-temple-red/20 object-cover shadow-lg">
|
|
<div class="flex-1">
|
|
<h3 class="text-lg font-bold text-gray-900 mb-1">{{ applicant.full_name|default:"Applicant Name" }}</h3>
|
|
<p class="text-sm text-gray-600">{{ applicant.email }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{# MAIN TABBED INTERFACE #}
|
|
<div class="bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden">
|
|
|
|
{# Tab Navigation #}
|
|
<div class="border-b border-gray-200 overflow-x-auto">
|
|
<div class="flex min-w-max px-4 pt-4 gap-2">
|
|
<button class="tab-btn px-4 py-2 text-sm font-medium rounded-t-lg border-b-2 border-temple-red text-temple-red bg-temple-red/5 transition"
|
|
onclick="showTab('profile-details')"
|
|
data-tab="profile-details">
|
|
<i data-lucide="user-circle" class="w-4 h-4 mr-2 inline"></i>
|
|
{% trans "Profile Details" %}
|
|
</button>
|
|
<button class="tab-btn px-4 py-2 text-sm font-medium rounded-t-lg border-b-2 border-transparent hover:border-temple-red hover:text-temple-red hover:bg-temple-red/5 transition"
|
|
onclick="showTab('applications-history')"
|
|
data-tab="applications-history">
|
|
<i data-lucide="list-alt" class="w-4 h-4 mr-2 inline"></i>
|
|
{% trans "My Applications" %}
|
|
</button>
|
|
<button class="tab-btn px-4 py-2 text-sm font-medium rounded-t-lg border-b-2 border-transparent hover:border-temple-red hover:text-temple-red hover:bg-temple-red/5 transition"
|
|
onclick="showTab('document-management')"
|
|
data-tab="document-management">
|
|
<i data-lucide="file-upload" class="w-4 h-4 mr-2 inline"></i>
|
|
{% trans "Documents" %}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{# Tab Content #}
|
|
<div class="p-4 md:p-6">
|
|
|
|
{# Profile Details Tab #}
|
|
<div id="profile-details" class="tab-content">
|
|
|
|
<!-- Basic Information Section -->
|
|
<div class="mb-8">
|
|
<h4 class="mb-4 font-bold text-gray-900 flex items-center gap-2">
|
|
<i data-lucide="user" class="w-5 h-5 text-temple-red"></i>
|
|
{% trans "Basic Information" %}
|
|
</h4>
|
|
<div class="bg-gray-50 rounded-xl p-4 space-y-3">
|
|
<div class="flex justify-between items-start pb-3 border-b border-gray-200 last:border-0 last:pb-0">
|
|
<div class="flex items-center gap-2 text-gray-600">
|
|
<i data-lucide="badge" class="w-4 h-4 text-temple-red"></i>
|
|
<span class="font-semibold text-gray-700">{% trans "First Name" %}</span>
|
|
</div>
|
|
<span class="text-gray-900 font-medium">{{ applicant.first_name|default:"" }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-start pb-3 border-b border-gray-200 last:border-0 last:pb-0">
|
|
<div class="flex items-center gap-2 text-gray-600">
|
|
<i data-lucide="badge" class="w-4 h-4 text-temple-red"></i>
|
|
<span class="font-semibold text-gray-700">{% trans "Last Name" %}</span>
|
|
</div>
|
|
<span class="text-gray-900 font-medium">{{ applicant.last_name|default:"" }}</span>
|
|
</div>
|
|
{% if applicant.middle_name %}
|
|
<div class="flex justify-between items-start pb-3 border-b border-gray-200 last:border-0 last:pb-0">
|
|
<div class="flex items-center gap-2 text-gray-600">
|
|
<i data-lucide="badge" class="w-4 h-4 text-temple-red"></i>
|
|
<span class="font-semibold text-gray-700">{% trans "Middle Name" %}</span>
|
|
</div>
|
|
<span class="text-gray-900 font-medium">{{ applicant.middle_name }}</span>
|
|
</div>
|
|
{% endif %}
|
|
<div class="flex justify-between items-start pb-3 border-b border-gray-200 last:border-0 last:pb-0">
|
|
<div class="flex items-center gap-2 text-gray-600">
|
|
<i data-lucide="mail" class="w-4 h-4 text-temple-red"></i>
|
|
<span class="font-semibold text-gray-700">{% trans "Email" %}</span>
|
|
</div>
|
|
<span class="text-gray-900 font-medium">{{ applicant.email|default:"" }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Contact Information Section -->
|
|
<div class="mb-8">
|
|
<h4 class="mb-4 font-bold text-gray-900 flex items-center gap-2">
|
|
<i data-lucide="address-book" class="w-5 h-5 text-temple-red"></i>
|
|
{% trans "Contact Information" %}
|
|
</h4>
|
|
<div class="bg-gray-50 rounded-xl p-4 space-y-3">
|
|
<div class="flex justify-between items-start pb-3 border-b border-gray-200 last:border-0 last:pb-0">
|
|
<div class="flex items-center gap-2 text-gray-600">
|
|
<i data-lucide="phone" class="w-4 h-4 text-temple-red"></i>
|
|
<span class="font-semibold text-gray-700">{% trans "Phone" %}</span>
|
|
</div>
|
|
<span class="text-gray-900 font-medium">{{ applicant.phone|default:"" }}</span>
|
|
</div>
|
|
{% if applicant.address %}
|
|
<div class="flex justify-between items-start pb-3 border-b border-gray-200 last:border-0 last:pb-0">
|
|
<div class="flex items-center gap-2 text-gray-600">
|
|
<i data-lucide="map-pin" class="w-4 h-4 text-temple-red"></i>
|
|
<span class="font-semibold text-gray-700">{% trans "Address" %}</span>
|
|
</div>
|
|
<span class="text-gray-900 font-medium text-right max-w-xs">{{ applicant.address|linebreaksbr }}</span>
|
|
</div>
|
|
{% endif %}
|
|
{% if applicant.linkedin_profile %}
|
|
<div class="flex justify-between items-start pb-3 border-b border-gray-200 last:border-0 last:pb-0">
|
|
<div class="flex items-center gap-2 text-gray-600">
|
|
<i data-lucide="linkedin" class="w-4 h-4 text-temple-red"></i>
|
|
<span class="font-semibold text-gray-700">{% trans "LinkedIn Profile" %}</span>
|
|
</div>
|
|
<a href="{{ applicant.linkedin_profile }}" target="_blank" class="text-temple-red hover:text-temple-red-dark font-medium flex items-center gap-1">
|
|
{% trans "View Profile" %} <i data-lucide="external-link" class="w-3 h-3"></i>
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Personal Details Section -->
|
|
<div class="mb-8">
|
|
<h4 class="mb-4 font-bold text-gray-900 flex items-center gap-2">
|
|
<i data-lucide="user-circle" class="w-5 h-5 text-temple-red"></i>
|
|
{% trans "Personal Details" %}
|
|
</h4>
|
|
<div class="bg-gray-50 rounded-xl p-4 space-y-3">
|
|
<div class="flex justify-between items-start pb-3 border-b border-gray-200 last:border-0 last:pb-0">
|
|
<div class="flex items-center gap-2 text-gray-600">
|
|
<i data-lucide="calendar" class="w-4 h-4 text-temple-red"></i>
|
|
<span class="font-semibold text-gray-700">{% trans "Date of Birth" %}</span>
|
|
</div>
|
|
<span class="text-gray-900 font-medium">{{ applicant.date_of_birth|date:"M d, Y"|default:"" }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-start pb-3 border-b border-gray-200 last:border-0 last:pb-0">
|
|
<div class="flex items-center gap-2 text-gray-600">
|
|
<i data-lucide="venus-mars" class="w-4 h-4 text-temple-red"></i>
|
|
<span class="font-semibold text-gray-700">{% trans "Gender" %}</span>
|
|
</div>
|
|
<span class="text-gray-900 font-medium">{{ applicant.get_gender_display|default:"" }}</span>
|
|
</div>
|
|
<div class="flex justify-between items-start pb-3 border-b border-gray-200 last:border-0 last:pb-0">
|
|
<div class="flex items-center gap-2 text-gray-600">
|
|
<i data-lucide="globe" class="w-4 h-4 text-temple-red"></i>
|
|
<span class="font-semibold text-gray-700">{% trans "Nationality" %}</span>
|
|
</div>
|
|
<span class="text-gray-900 font-medium">{{ applicant.get_nationality_display|default:"" }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Professional Information Section -->
|
|
<div class="mb-8">
|
|
<h4 class="mb-4 font-bold text-gray-900 flex items-center gap-2">
|
|
<i data-lucide="briefcase" class="w-5 h-5 text-temple-red"></i>
|
|
{% trans "Professional Information" %}
|
|
</h4>
|
|
<div class="bg-gray-50 rounded-xl p-4 space-y-3">
|
|
{% if applicant.user.designation %}
|
|
<div class="flex justify-between items-start pb-3 border-b border-gray-200 last:border-0 last:pb-0">
|
|
<div class="flex items-center gap-2 text-gray-600">
|
|
<i data-lucide="user-tie" class="w-4 h-4 text-temple-red"></i>
|
|
<span class="font-semibold text-gray-700">{% trans "Designation" %}</span>
|
|
</div>
|
|
<span class="text-gray-900 font-medium">{{ applicant.user.designation }}</span>
|
|
</div>
|
|
{% endif %}
|
|
{% if applicant.gpa %}
|
|
<div class="flex justify-between items-start pb-3 border-b border-gray-200 last:border-0 last:pb-0">
|
|
<div class="flex items-center gap-2 text-gray-600">
|
|
<i data-lucide="graduation-cap" class="w-4 h-4 text-temple-red"></i>
|
|
<span class="font-semibold text-gray-700">{% trans "GPA" %}</span>
|
|
</div>
|
|
<span class="text-gray-900 font-medium">{{ applicant.gpa }}</span>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{# Applications History Tab #}
|
|
<div id="applications-history" class="tab-content hidden">
|
|
<h4 class="mb-4 font-bold text-gray-900 flex items-center gap-2">
|
|
<i data-lucide="list-checks" class="w-5 h-5 text-temple-red"></i>
|
|
{% trans "Application Tracking" %}
|
|
</h4>
|
|
|
|
{% if applications %}
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
{% for application in applications %}
|
|
<div class="bg-white rounded-xl border border-gray-200 shadow-sm hover:shadow-md hover:border-temple-red/30 transition-all duration-300">
|
|
<div class="p-5 flex flex-col h-full">
|
|
<!-- Job Title -->
|
|
<div class="mb-3">
|
|
<h5 class="font-bold text-gray-900 mb-2">
|
|
<a href="{% url 'applicant_application_detail' application.slug %}"
|
|
class="text-temple-red hover:text-temple-red-dark transition">
|
|
{{ application.job.title }}
|
|
</a>
|
|
</h5>
|
|
<p class="text-xs text-gray-500 flex items-center gap-1">
|
|
<i data-lucide="calendar" class="w-3 h-3"></i>
|
|
{% trans "Applied" %}: {{ application.created_at|date:"d M Y" }}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Application Details -->
|
|
<div class="space-y-2 mb-4">
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-xs text-gray-600 font-medium">{% trans "Current Stage" %}</span>
|
|
<span class="text-xs font-bold px-2 py-1 rounded-full bg-temple-red text-white">
|
|
{{ application.stage }}
|
|
</span>
|
|
</div>
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-xs text-gray-600 font-medium">{% trans "Status" %}</span>
|
|
{% if application.is_active %}
|
|
<span class="text-xs font-bold px-2 py-1 rounded-full bg-emerald-500 text-white">{% trans "Active" %}</span>
|
|
{% else %}
|
|
<span class="text-xs font-bold px-2 py-1 rounded-full bg-red-500 text-white">{% trans "Closed" %}</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Action Button -->
|
|
<div class="mt-auto">
|
|
<a href="{% url 'applicant_application_detail' application.slug %}"
|
|
class="inline-flex items-center justify-center gap-2 w-full bg-temple-red hover:bg-temple-red-dark text-white font-medium py-2.5 rounded-xl text-sm transition shadow-sm hover:shadow-md">
|
|
<i data-lucide="eye" class="w-4 h-4"></i>
|
|
{% trans "View Details" %}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<div class="bg-temple-red/5 border-2 border-dashed border-temple-red/30 rounded-2xl p-8 text-center">
|
|
<i data-lucide="info" class="w-12 h-12 text-temple-red mx-auto mb-4"></i>
|
|
<h5 class="mb-3 font-bold text-gray-900">{% trans "You haven't submitted any applications yet." %}</h5>
|
|
<a href="{% url 'kaauh_career' %}" class="inline-flex items-center gap-2 bg-temple-red hover:bg-temple-red-dark text-white font-medium px-6 py-2.5 rounded-xl text-sm transition shadow-sm hover:shadow-md">
|
|
{% trans "View Available Jobs" %} <i data-lucide="arrow-right" class="w-4 h-4"></i>
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{# Document Management Tab #}
|
|
<div id="document-management" class="tab-content hidden">
|
|
<h4 class="mb-4 font-bold text-gray-900 flex items-center gap-2">
|
|
<i data-lucide="file-text" class="w-5 h-5 text-temple-red"></i>
|
|
{% trans "My Uploaded Documents" %}
|
|
</h4>
|
|
|
|
<p class="text-sm text-gray-600 mb-6">
|
|
{% trans "You can upload and manage your resume, certificates, and professional documents here. These documents will be attached to your applications." %}
|
|
</p>
|
|
|
|
<button type="button" class="inline-flex items-center gap-2 bg-temple-red hover:bg-temple-red-dark text-white font-medium px-4 py-2.5 rounded-xl text-sm transition shadow-sm hover:shadow-md mb-6"
|
|
onclick="document.getElementById('documentUploadModal').classList.remove('hidden')">
|
|
<i data-lucide="upload-cloud" class="w-4 h-4"></i>
|
|
{% trans "Upload New Document" %}
|
|
</button>
|
|
|
|
<div class="border-t border-gray-200"></div>
|
|
|
|
{# Document List #}
|
|
<div class="space-y-3 mt-6">
|
|
{% for document in documents %}
|
|
<div class="bg-gray-50 rounded-xl p-4 flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3"
|
|
id="document-{{ document.id }}">
|
|
<div class="flex-1">
|
|
<div class="flex items-center gap-2 font-semibold text-gray-900">
|
|
<i data-lucide="file" class="w-4 h-4 text-temple-red"></i>
|
|
<span>{{ document.document_type|title }}</span>
|
|
</div>
|
|
<span class="text-xs text-gray-500">({{ document.file.name|split:"/"|last }})</span>
|
|
</div>
|
|
<div class="flex items-center gap-3">
|
|
<span class="text-xs text-gray-500">{% trans "Uploaded:" %} {{ document.uploaded_at|date:"d M Y" }}</span>
|
|
<a href="{{ document.file.url }}" target="_blank" class="text-gray-600 hover:text-temple-red transition">
|
|
<i data-lucide="eye" class="w-4 h-4"></i>
|
|
</a>
|
|
<button hx-post="{% url 'document_delete' document.pk %}"
|
|
hx-target="#document-{{ document.id }}"
|
|
hx-swap="outerHTML"
|
|
hx-confirm="{% trans 'Are you sure you want to delete this file?' %}"
|
|
class="text-red-500 hover:text-red-600 transition">
|
|
<i data-lucide="trash-2" class="w-4 h-4"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
{% empty %}
|
|
<div class="bg-gray-50 rounded-xl p-8 text-center">
|
|
<i data-lucide="folder-open" class="w-12 h-12 text-gray-300 mx-auto mb-4"></i>
|
|
<p class="text-gray-500">{% trans "No documents uploaded yet." %}</p>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{# Modals with modern styling #}
|
|
<div id="documentUploadModal" class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 hidden flex items-center justify-center p-4">
|
|
<div class="bg-white rounded-2xl shadow-xl max-w-lg w-full max-h-[90vh] overflow-y-auto">
|
|
<div class="flex items-center justify-between p-6 border-b border-gray-200">
|
|
<h5 class="text-lg font-bold text-gray-900">{% trans "Upload Document" %}</h5>
|
|
<button onclick="document.getElementById('documentUploadModal').classList.add('hidden')" class="text-gray-400 hover:text-gray-600 transition">
|
|
<i data-lucide="x" class="w-5 h-5"></i>
|
|
</button>
|
|
</div>
|
|
<div class="p-6">
|
|
{% include "forms/document_form.html" with slug=applicant.slug %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
lucide.createIcons();
|
|
|
|
// Tab switching functionality
|
|
function showTab(tabId) {
|
|
// Hide all tab contents
|
|
document.querySelectorAll('.tab-content').forEach(content => {
|
|
content.classList.add('hidden');
|
|
});
|
|
|
|
// Remove active state from all tabs
|
|
document.querySelectorAll('.tab-btn').forEach(btn => {
|
|
btn.classList.remove('border-temple-red', 'text-temple-red', 'bg-temple-red/5');
|
|
btn.classList.add('border-transparent', 'text-gray-600');
|
|
});
|
|
|
|
// Show selected tab content
|
|
document.getElementById(tabId).classList.remove('hidden');
|
|
|
|
// Add active state to selected tab
|
|
const activeBtn = document.querySelector(`[data-tab="${tabId}"]`);
|
|
activeBtn.classList.add('border-temple-red', 'text-temple-red', 'bg-temple-red/5');
|
|
activeBtn.classList.remove('border-transparent', 'text-gray-600');
|
|
}
|
|
|
|
// Initialize first tab as active
|
|
showTab('profile-details');
|
|
</script>
|
|
|
|
{% endblock %} |