402 lines
21 KiB
HTML
402 lines
21 KiB
HTML
{% extends "base.html" %}
|
|
{% load static i18n %}
|
|
|
|
{% block title %}{{ person.get_full_name }} - {{ block.super }}{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="max-w-6xl mx-auto py-6 px-4">
|
|
|
|
<!-- Breadcrumb -->
|
|
<nav class="mb-6" aria-label="breadcrumb">
|
|
<ol class="flex items-center gap-2 text-sm flex-wrap">
|
|
<li><a href="{% url 'person_list' %}" class="text-gray-500 hover:underline transition flex items-center gap-1">
|
|
<i data-lucide="users" class="w-4 h-4"></i> {% trans "Applicants" %}
|
|
</a></li>
|
|
<li class="text-gray-400">/</li>
|
|
<li class="font-semibold" style="color: #9d2235;">{{ person.full_name|title }}</li>
|
|
</ol>
|
|
</nav>
|
|
|
|
<!-- Profile Header -->
|
|
<div class="bg-white rounded-xl shadow-sm border border-gray-200 mb-6 overflow-hidden">
|
|
<div class="px-6 py-4" style="background: linear-gradient(135deg, #9d2235 0%, #7a1a29 100%); color: white;">
|
|
<div class="flex flex-col sm:flex-row items-center sm:items-start gap-6">
|
|
<div class="flex-shrink-0">
|
|
{% if person.profile_image %}
|
|
<img src="{{ person.profile_image.url }}" alt="{{ person.get_full_name }}"
|
|
class="w-32 h-32 rounded-full border-4 border-white/30 object-cover shadow-lg">
|
|
{% else %}
|
|
<div class="w-32 h-32 rounded-full bg-white/30 flex items-center justify-center border-4 border-white/30">
|
|
<i data-lucide="user" class="w-16 h-16 text-white/80"></i>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="flex-1 text-center sm:text-left">
|
|
<h1 class="text-3xl font-bold mb-2">{{ person.get_full_name }}</h1>
|
|
{% if person.email %}
|
|
<p class="text-lg text-white/90 mb-3">
|
|
<i data-lucide="mail" class="inline w-4 h-4 mr-2"></i>{{ person.email }}
|
|
</p>
|
|
{% endif %}
|
|
<div class="flex flex-wrap gap-2 justify-center sm:justify-start mb-3">
|
|
{% if person.nationality %}
|
|
<span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-white/20 text-white">
|
|
<i data-lucide="globe" class="w-3 h-3 mr-1"></i>{{ person.nationality }}
|
|
</span>
|
|
{% endif %}
|
|
{% if person.gender %}
|
|
<span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-white/20 text-white">
|
|
{% if person.gender == 'M' %}{% trans "Male" %}{% else %}{% trans "Female" %}{% endif %}
|
|
</span>
|
|
{% endif %}
|
|
{% if person.user %}
|
|
<span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-green-500/80 text-white">
|
|
<i data-lucide="user-check" class="w-3 h-3 mr-1"></i>{% trans "User Account" %}
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
|
|
<!-- Personal Information -->
|
|
<div class="bg-white rounded-xl shadow-sm border border-gray-200">
|
|
<div class="px-6 py-4 border-b border-gray-100" style="background-color: #f8f9fa;">
|
|
<h2 class="text-lg font-bold flex items-center gap-2">
|
|
<i data-lucide="user" class="w-5 h-5" style="color: #9d2235;"></i>
|
|
{% trans "Personal Information" %}
|
|
</h2>
|
|
</div>
|
|
<div class="p-6 space-y-4">
|
|
<div class="flex items-start gap-3 p-3 rounded-lg hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="user" class="w-5 h-5 mt-0.5 flex-shrink-0" style="color: #9d2235;"></i>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold text-gray-600 block">{% trans "Full Name" %}</span>
|
|
<span class="text-gray-900">{{ person.full_name|title }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
{% if person.first_name %}
|
|
<div class="flex items-start gap-3 p-3 rounded-lg hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="user" class="w-5 h-5 mt-0.5 flex-shrink-0" style="color: #9d2235;"></i>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold text-gray-600 block">{% trans "First Name" %}</span>
|
|
<span class="text-gray-900">{{ person.first_name }}</span>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if person.last_name %}
|
|
<div class="flex items-start gap-3 p-3 rounded-lg hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="user" class="w-5 h-5 mt-0.5 flex-shrink-0" style="color: #9d2235;"></i>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold text-gray-600 block">{% trans "Last Name" %}</span>
|
|
<span class="text-gray-900">{{ person.last_name }}</span>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if person.date_of_birth %}
|
|
<div class="flex items-start gap-3 p-3 rounded-lg hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="calendar" class="w-5 h-5 mt-0.5 flex-shrink-0" style="color: #9d2235;"></i>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold text-gray-600 block">{% trans "Date of Birth" %}</span>
|
|
<span class="text-gray-900">{{ person.date_of_birth }}</span>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if person.gender %}
|
|
<div class="flex items-start gap-3 p-3 rounded-lg hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="user-2" class="w-5 h-5 mt-0.5 flex-shrink-0" style="color: #9d2235;"></i>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold text-gray-600 block">{% trans "Gender" %}</span>
|
|
<span class="text-gray-900">
|
|
{% if person.gender == 'M' %}{% trans "Male" %}{% else %}{% trans "Female" %}{% endif %}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if person.nationality %}
|
|
<div class="flex items-start gap-3 p-3 rounded-lg hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="globe" class="w-5 h-5 mt-0.5 flex-shrink-0" style="color: #9d2235;"></i>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold text-gray-600 block">{% trans "Nationality" %}</span>
|
|
<span class="text-gray-900">{{ person.nationality }}</span>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Contact Information -->
|
|
<div class="bg-white rounded-xl shadow-sm border border-gray-200">
|
|
<div class="px-6 py-4 border-b border-gray-100" style="background-color: #f8f9fa;">
|
|
<h2 class="text-lg font-bold flex items-center gap-2">
|
|
<i data-lucide="mail" class="w-5 h-5" style="color: #9d2235;"></i>
|
|
{% trans "Contact Information" %}
|
|
</h2>
|
|
</div>
|
|
<div class="p-6 space-y-4">
|
|
{% if person.email %}
|
|
<div class="flex items-start gap-3 p-3 rounded-lg hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="mail" class="w-5 h-5 mt-0.5 flex-shrink-0" style="color: #9d2235;"></i>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold text-gray-600 block">{% trans "Email" %}</span>
|
|
<a href="mailto:{{ person.email }}" class="text-gray-900 hover:underline" style="color: #9d2235;">
|
|
{{ person.email }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if person.phone %}
|
|
<div class="flex items-start gap-3 p-3 rounded-lg hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="phone" class="w-5 h-5 mt-0.5 flex-shrink-0" style="color: #9d2235;"></i>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold text-gray-600 block">{% trans "Phone" %}</span>
|
|
<a href="tel:{{ person.phone }}" class="text-gray-900 hover:underline" style="color: #9d2235;">
|
|
{{ person.phone }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if person.address %}
|
|
<div class="flex items-start gap-3 p-3 rounded-lg hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="map-pin" class="w-5 h-5 mt-0.5 flex-shrink-0" style="color: #9d2235;"></i>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold text-gray-600 block">{% trans "Address" %}</span>
|
|
<span class="text-gray-900 whitespace-pre-line">{{ person.address }}</span>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if person.linkedin_profile %}
|
|
<div class="flex items-start gap-3 p-3 rounded-lg hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="linkedin" class="w-5 h-5 mt-0.5 flex-shrink-0" style="color: #9d2235;"></i>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold text-gray-600 block">{% trans "LinkedIn" %}</span>
|
|
<a href="{{ person.linkedin_profile }}" target="_blank" class="text-gray-900 hover:underline" style="color: #9d2235;">
|
|
{% trans "View Profile" %}
|
|
<i data-lucide="external-link" class="inline w-4 h-4 ml-1"></i>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Related Information -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
|
|
<!-- Applications -->
|
|
<div class="bg-white rounded-xl shadow-sm border border-gray-200">
|
|
<div class="px-6 py-4 border-b border-gray-100" style="background-color: #f8f9fa;">
|
|
<h2 class="text-lg font-bold flex items-center gap-2">
|
|
<i data-lucide="briefcase" class="w-5 h-5" style="color: #9d2235;"></i>
|
|
{% trans "Applications" %}
|
|
<span class="inline-flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold text-white ml-2" style="background-color: #9d2235;">
|
|
{{ person.applications.count }}
|
|
</span>
|
|
</h2>
|
|
</div>
|
|
<div class="p-6">
|
|
{% if person.applications %}
|
|
<div class="space-y-4">
|
|
{% for application in person.applications.all %}
|
|
<div class="pl-4 hover:bg-gray-50 p-3 rounded-lg transition-colors" style="border-left: 3px solid #9d2235;">
|
|
<div class="flex justify-between items-start">
|
|
<div class="flex-1">
|
|
<a href="{% url 'application_detail' application.slug %}"
|
|
class="font-semibold text-gray-900 hover:underline" style="color: #9d2235;">
|
|
{{ application.job.title }}
|
|
</a>
|
|
<p class="text-sm text-gray-500 mt-1">
|
|
{% trans "Applied" %}: {{ application.created_at|date:"d M Y" }}
|
|
</p>
|
|
</div>
|
|
<span class="inline-flex items-center px-2.5 py-1 rounded-full text-xs font-semibold text-white" style="background-color: #9d2235;">
|
|
{{ application.stage }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<div class="text-center py-8 text-gray-500">
|
|
<i data-lucide="briefcase" class="w-16 h-16 mx-auto mb-3" style="color: #9d2235; opacity: 0.3;"></i>
|
|
<p>{% trans "No applications found" %}</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Documents -->
|
|
<div class="bg-white rounded-xl shadow-sm border border-gray-200">
|
|
<div class="px-6 py-4 border-b border-gray-100" style="background-color: #f8f9fa;">
|
|
<h2 class="text-lg font-bold flex items-center gap-2">
|
|
<i data-lucide="file-text" class="w-5 h-5" style="color: #9d2235;"></i>
|
|
{% trans "Documents" %}
|
|
<span class="inline-flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold text-white ml-2" style="background-color: #9d2235;">
|
|
{{ person.documents.count }}
|
|
</span>
|
|
</h2>
|
|
</div>
|
|
<div class="p-6">
|
|
{% if person.documents %}
|
|
<div class="space-y-4">
|
|
{% for document in person.documents %}
|
|
<div class="pl-4 hover:bg-gray-50 p-3 rounded-lg transition-colors" style="border-left: 3px solid #9d2235;">
|
|
<div class="flex justify-between items-center">
|
|
<div class="flex-1">
|
|
<a href="{{ document.file.url }}" target="_blank"
|
|
class="font-semibold text-gray-900 hover:underline" style="color: #9d2235;">
|
|
{{ document.filename }}
|
|
</a>
|
|
<p class="text-sm text-gray-500 mt-1">
|
|
{{ document.file_size|filesizeformat }} • {{ document.uploaded_at|date:"d M Y" }}
|
|
</p>
|
|
</div>
|
|
<a href="{{ document.file.url }}" download="{{ document.filename }}"
|
|
class="inline-flex items-center gap-1 px-3 py-2 rounded-lg text-sm font-medium border-2 border-gray-300 text-gray-600 hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="download" class="w-4 h-4"></i>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<div class="text-center py-8 text-gray-500">
|
|
<i data-lucide="file-text" class="w-16 h-16 mx-auto mb-3" style="color: #9d2235; opacity: 0.3;"></i>
|
|
<p>{% trans "No documents found" %}</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- System Information -->
|
|
<div class="bg-white rounded-xl shadow-sm border border-gray-200 mb-6">
|
|
<div class="px-6 py-4 border-b border-gray-100" style="background-color: #f8f9fa;">
|
|
<h2 class="text-lg font-bold flex items-center gap-2">
|
|
<i data-lucide="info" class="w-5 h-5" style="color: #9d2235;"></i>
|
|
{% trans "System Information" %}
|
|
</h2>
|
|
</div>
|
|
<div class="p-6">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div class="flex items-start gap-3 p-3 rounded-lg hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="calendar-plus" class="w-5 h-5 mt-0.5 flex-shrink-0" style="color: #9d2235;"></i>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold text-gray-600 block">{% trans "Created" %}</span>
|
|
<span class="text-gray-900">{{ person.created_at|date:"d M Y H:i" }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex items-start gap-3 p-3 rounded-lg hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="edit-2" class="w-5 h-5 mt-0.5 flex-shrink-0" style="color: #9d2235;"></i>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold text-gray-600 block">{% trans "Last Updated" %}</span>
|
|
<span class="text-gray-900">{{ person.updated_at|date:"d M Y H:i" }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
{% if person.user.last_login %}
|
|
<div class="flex items-start gap-3 p-3 rounded-lg hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="clock" class="w-5 h-5 mt-0.5 flex-shrink-0" style="color: #9d2235;"></i>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold text-gray-600 block">{% trans "Last Login" %}</span>
|
|
<span class="text-gray-900">{{ person.user.last_login|date:"d M Y H:i" }}</span>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if person.user %}
|
|
<div class="flex items-start gap-3 p-3 rounded-lg hover:bg-gray-50 transition-colors">
|
|
<i data-lucide="shield" class="w-5 h-5 mt-0.5 flex-shrink-0" style="color: #9d2235;"></i>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold text-gray-600 block">{% trans "User Account" %}</span>
|
|
<a href="{% url 'user_detail' person.user.pk %}" class="text-gray-900 hover:underline" style="color: #9d2235;">
|
|
{{ person.user.username }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Action Buttons -->
|
|
<div class="flex flex-col sm:flex-row justify-between items-center gap-4">
|
|
<a href="{% url 'person_list' %}"
|
|
class="inline-flex items-center gap-2 px-6 py-3 rounded-lg font-medium border-2 border-gray-200 text-gray-700 hover:bg-gray-50 transition-all duration-200">
|
|
<i data-lucide="arrow-left" class="w-4 h-4"></i>
|
|
{% trans "Back to Applicants" %}
|
|
</a>
|
|
|
|
{% if user.is_staff %}
|
|
<div class="flex flex-wrap gap-3">
|
|
<button type="button" onclick="window.location.href='{% url 'password_reset' person.slug %}'"
|
|
class="inline-flex items-center gap-2 px-6 py-3 rounded-lg font-medium border-2 border-gray-200 text-gray-700 hover:bg-gray-50 transition-all duration-200">
|
|
<i data-lucide="lock" class="w-4 h-4"></i>
|
|
{% trans "Set Staff Password" %}
|
|
</button>
|
|
<a href="{% url 'person_update' person.slug %}"
|
|
class="inline-flex items-center gap-2 px-6 py-3 rounded-lg font-medium text-white transition-all duration-200"
|
|
style="background-color: #9d2235;"
|
|
onmouseover="this.style.backgroundColor='#7a1a29'"
|
|
onmouseout="this.style.backgroundColor='#9d2235'">
|
|
<i data-lucide="edit-2" class="w-4 h-4"></i>
|
|
{% trans "Edit Applicant" %}
|
|
</a>
|
|
<a href="{% url 'person_delete' person.slug %}"
|
|
class="inline-flex items-center gap-2 px-6 py-3 rounded-lg font-medium text-white bg-red-600 hover:bg-red-700 transition-all duration-200">
|
|
<i data-lucide="trash-2" class="w-4 h-4"></i>
|
|
{% trans "Delete" %}
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<script>
|
|
// Initialize Lucide icons
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
if (typeof lucide !== 'undefined') {
|
|
lucide.createIcons();
|
|
}
|
|
|
|
// Add hover effects for cards
|
|
const cards = document.querySelectorAll('.bg-white');
|
|
cards.forEach(card => {
|
|
card.addEventListener('mouseenter', function() {
|
|
this.style.transform = 'translateY(-2px)';
|
|
this.style.transition = 'transform 0.2s ease';
|
|
});
|
|
|
|
card.addEventListener('mouseleave', function() {
|
|
this.style.transform = 'translateY(0)';
|
|
});
|
|
});
|
|
|
|
// Smooth scroll for anchor links
|
|
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
|
anchor.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
const target = document.querySelector(this.getAttribute('href'));
|
|
if (target) {
|
|
target.scrollIntoView({
|
|
behavior: 'smooth',
|
|
block: 'start'
|
|
});
|
|
}
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %} |