HH/templates/organizations/staff_detail.html
ismail c5f76b3855
Some checks are pending
Build and Push Docker Image / build (push) Waiting to run
updates
2026-05-11 14:45:30 +03:00

758 lines
42 KiB
HTML

{% extends "layouts/base.html" %}
{% load i18n %}
{% block title %}{{ staff.get_full_name }} - {% trans "Staff Details" %}{% endblock %}
{% block content %}
<!-- Back Button -->
<div class="mb-6">
<a href="{% url 'organizations:staff_list' %}" class="inline-flex items-center gap-2 px-4 py-2 border border-slate-200 rounded-xl text-slate hover:text-navy hover:bg-light transition text-sm font-semibold">
<i data-lucide="arrow-left" class="w-4 h-4"></i> {% trans "Back to Staff List" %}
</a>
</div>
<!-- Breadcrumb & Header -->
<header class="mb-6">
<div class="flex items-center gap-2 text-sm text-slate mb-2">
<a href="{% url 'organizations:staff_list' %}">{% trans "Staff" %}</a>
<i data-lucide="chevron-right" class="w-4 h-4"></i>
<span class="font-bold text-navy">{{ staff.get_full_name }}</span>
{% if staff.status == 'active' %}
<span class="ml-2 px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider bg-green-100 text-green-700">{% trans "Active" %}</span>
{% else %}
<span class="ml-2 px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider bg-slate-100 text-slate-700">{% trans "Inactive" %}</span>
{% endif %}
</div>
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<div class="w-14 h-14 bg-navy rounded-2xl flex items-center justify-center text-white font-bold text-xl">
{{ staff.get_localized_name.0 }}
</div>
<div>
<h1 class="text-2xl font-bold text-navy">{{ staff.get_localized_name }}</h1>
<p class="text-slate text-sm">{{ staff.job_title|default:"-" }} <span class="text-slate-300">|</span> {{ staff.get_department_type_display }}</p>
</div>
{% if staff.is_head %}
<span class="bg-yellow-100 text-yellow-700 text-xs px-3 py-1.5 rounded-full font-bold flex items-center gap-1">
<i data-lucide="crown" class="w-3 h-3"></i> {% trans "Department Head" %}
</span>
{% endif %}
</div>
<div class="flex items-center gap-3">
{% if user.is_px_admin or user.is_hospital_admin %}
<a href="{% url 'organizations:staff_update' staff.id %}" class="bg-navy text-white px-5 py-2.5 rounded-xl text-sm font-bold hover:bg-blue flex items-center gap-2 transition shadow-lg shadow-navy/20">
<i data-lucide="edit" class="w-4 h-4"></i> {% trans "Edit" %}
</a>
{% endif %}
</div>
</div>
</header>
<!-- Main Content Grid -->
<div class="grid grid-cols-12 gap-8">
<!-- Left Column (Content) -->
<div class="col-span-8 space-y-6">
<!-- Personal Information -->
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
<h3 class="font-bold text-navy mb-6 text-lg flex items-center gap-2">
<i data-lucide="user" class="w-5 h-5 text-blue"></i>
{% trans "Personal Information" %}
</h3>
<div class="grid grid-cols-2 gap-6">
<div>
<label class="text-xs font-bold text-slate uppercase block mb-1">{% trans "First Name (English)" %}</label>
<div class="font-bold text-navy">{{ staff.first_name }}</div>
</div>
<div>
<label class="text-xs font-bold text-slate uppercase block mb-1">{% trans "Last Name (English)" %}</label>
<div class="font-bold text-navy">{{ staff.last_name }}</div>
</div>
<div>
<label class="text-xs font-bold text-slate uppercase block mb-1">{% trans "First Name (Arabic)" %}</label>
<div class="font-bold text-navy" dir="rtl">{{ staff.first_name_ar|default:"-" }}</div>
</div>
<div>
<label class="text-xs font-bold text-slate uppercase block mb-1">{% trans "Last Name (Arabic)" %}</label>
<div class="font-bold text-navy" dir="rtl">{{ staff.last_name_ar|default:"-" }}</div>
</div>
{% if staff.license_number %}
<div>
<label class="text-xs font-bold text-slate uppercase block mb-1">{% trans "License Number" %}</label>
<div class="font-bold text-slate-800">{{ staff.license_number }}</div>
</div>
{% endif %}
{% if staff.specialization %}
<div>
<label class="text-xs font-bold text-slate uppercase block mb-1">{% trans "Specialization" %}</label>
<div class="font-bold text-slate-800">{{ staff.specialization }}</div>
</div>
{% endif %}
</div>
</section>
<!-- Organization -->
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
<h3 class="font-bold text-navy mb-6 text-lg flex items-center gap-2">
<i data-lucide="building-2" class="w-5 h-5 text-blue"></i>
{% trans "Organization" %}
</h3>
<div class="grid grid-cols-2 gap-6">
<div>
<label class="text-xs font-bold text-slate uppercase block mb-1">{% trans "Hospital" %}</label>
<div class="font-bold text-navy">{{ staff.hospital.name }}</div>
</div>
<div>
<label class="text-xs font-bold text-slate uppercase block mb-1">{% trans "Department" %}</label>
<div class="font-bold text-slate-800">{{ staff.department.name|default:"-" }}</div>
</div>
<div>
<label class="text-xs font-bold text-slate uppercase block mb-1">{% trans "Employee ID" %}</label>
<div class="font-bold text-slate-800">{{ staff.employee_id|default:"-" }}</div>
</div>
<div>
<label class="text-xs font-bold text-slate uppercase block mb-1">{% trans "Section" %}</label>
<div class="font-bold text-slate-800">{{ staff.section|default:"-" }}</div>
</div>
</div>
</section>
<!-- Contact Information -->
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
<h3 class="font-bold text-navy mb-6 text-lg flex items-center gap-2">
<i data-lucide="mail" class="w-5 h-5 text-blue"></i>
{% trans "Contact Information" %}
</h3>
<div class="grid grid-cols-2 gap-6">
<div>
<label class="text-xs font-bold text-slate uppercase block mb-1">{% trans "Email" %}</label>
<div class="font-bold text-slate-800">
{% if staff.email %}
<a href="mailto:{{ staff.email }}" class="text-blue hover:underline">{{ staff.email }}</a>
{% else %}
<span class="text-slate">-</span>
{% endif %}
</div>
</div>
<div>
<label class="text-xs font-bold text-slate uppercase block mb-1">{% trans "Phone" %}</label>
<div class="font-bold text-slate-800">
{% if staff.phone %}
<a href="tel:{{ staff.phone }}" class="text-blue hover:underline">{{ staff.phone }}</a>
{% else %}
<span class="text-slate">-</span>
{% endif %}
</div>
</div>
</div>
</section>
<!-- Hierarchy -->
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
<h3 class="font-bold text-navy mb-6 text-lg flex items-center gap-2">
<i data-lucide="git-branch" class="w-5 h-5 text-blue"></i>
{% trans "Hierarchy" %}
</h3>
<div class="space-y-4">
<div class="flex justify-between items-center border-b border-slate-100 pb-3">
<span class="text-xs font-bold text-slate uppercase">{% trans "Reports To" %}</span>
<span class="font-bold text-slate-800">
{% if staff.report_to %}
<a href="{% url 'organizations:staff_detail' staff.report_to.id %}" class="text-blue hover:underline flex items-center gap-1">
{{ staff.report_to.get_full_name }}
</a>
{% else %}
<span class="text-slate">-</span>
{% endif %}
</span>
</div>
<div>
<span class="text-xs font-bold text-slate uppercase block mb-2">{% trans "Direct Reports" %}</span>
{% if staff.direct_reports.exists %}
<div class="flex flex-wrap gap-2">
{% for direct_report in staff.direct_reports.all %}
<a href="{% url 'organizations:staff_detail' direct_report.id %}" class="px-3 py-1.5 bg-light rounded-lg text-sm font-semibold text-navy hover:bg-blue-100 transition">
{{ direct_report.get_full_name }}
</a>
{% endfor %}
</div>
{% else %}
<span class="text-slate text-sm">-</span>
{% endif %}
</div>
</div>
</section>
<!-- Complaints -->
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
<div class="flex items-center justify-between mb-6">
<h3 class="font-bold text-navy text-lg flex items-center gap-2">
<i data-lucide="message-square-warning" class="w-5 h-5 text-blue"></i>
{% trans "Complaints" %}
<span class="bg-slate-100 text-slate-700 text-xs px-2.5 py-1 rounded-full font-bold">{{ complaint_counts.total }}</span>
</h3>
{% if complaint_counts.total > 0 %}
<a href="{% url 'organizations:staff_complaints_export' staff.id %}" class="bg-green-600 text-white px-4 py-2 rounded-xl text-sm font-bold hover:bg-green-700 flex items-center gap-2 transition shadow-sm">
<i data-lucide="file-spreadsheet" class="w-4 h-4"></i> {% trans "Export Excel" %}
</a>
{% endif %}
</div>
{% if complaint_counts.total > 0 %}
<!-- Summary badges -->
<div class="flex flex-wrap gap-3 mb-6">
{% if complaint_counts.open > 0 %}
<span class="bg-red-50 text-red-700 text-xs font-bold px-3 py-1.5 rounded-full flex items-center gap-1">
<span class="w-2 h-2 bg-red-500 rounded-full"></span>
{% trans "Open" %}: {{ complaint_counts.open }}
</span>
{% endif %}
{% if complaint_counts.in_progress > 0 %}
<span class="bg-blue-50 text-blue-700 text-xs font-bold px-3 py-1.5 rounded-full flex items-center gap-1">
<span class="w-2 h-2 bg-blue-500 rounded-full"></span>
{% trans "In Progress" %}: {{ complaint_counts.in_progress }}
</span>
{% endif %}
{% if complaint_counts.resolved > 0 %}
<span class="bg-green-50 text-green-700 text-xs font-bold px-3 py-1.5 rounded-full flex items-center gap-1">
<span class="w-2 h-2 bg-green-500 rounded-full"></span>
{% trans "Resolved" %}: {{ complaint_counts.resolved }}
</span>
{% endif %}
{% if complaint_counts.closed > 0 %}
<span class="bg-slate-50 text-slate-600 text-xs font-bold px-3 py-1.5 rounded-full flex items-center gap-1">
<span class="w-2 h-2 bg-slate-400 rounded-full"></span>
{% trans "Closed" %}: {{ complaint_counts.closed }}
</span>
{% endif %}
</div>
<!-- Complaints table -->
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-slate-200">
<th class="text-left py-3 px-3 text-xs font-bold text-slate uppercase">{% trans "Ref #" %}</th>
<th class="text-left py-3 px-3 text-xs font-bold text-slate uppercase">{% trans "Title" %}</th>
<th class="text-left py-3 px-3 text-xs font-bold text-slate uppercase">{% trans "Patient" %}</th>
<th class="text-left py-3 px-3 text-xs font-bold text-slate uppercase">{% trans "Status" %}</th>
<th class="text-left py-3 px-3 text-xs font-bold text-slate uppercase">{% trans "Severity" %}</th>
<th class="text-left py-3 px-3 text-xs font-bold text-slate uppercase">{% trans "Role" %}</th>
<th class="text-left py-3 px-3 text-xs font-bold text-slate uppercase">{% trans "Created" %}</th>
</tr>
</thead>
<tbody>
{% for row in complaint_rows %}
{% with complaint=row.complaint %}
<tr class="border-b border-slate-50 hover:bg-slate-50 transition">
<td class="py-3 px-3">
<a href="{% url 'complaints:complaint_detail' complaint.id %}" class="text-blue hover:underline font-semibold">
{{ complaint.reference_number|default:complaint.id|truncatechars:10 }}
</a>
</td>
<td class="py-3 px-3 font-medium text-navy max-w-xs truncate">{{ complaint.title|truncatechars:50 }}</td>
<td class="py-3 px-3 text-slate-600">
{% if complaint.patient %}
{{ complaint.patient.get_full_name|truncatechars:25 }}
{% elif complaint.patient_name %}
{{ complaint.patient_name|truncatechars:25 }}
{% else %}
-
{% endif %}
</td>
<td class="py-3 px-3">
{% if complaint.status == 'open' %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider bg-red-100 text-red-700">{% trans "Open" %}</span>
{% elif complaint.status == 'in_progress' %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider bg-blue-100 text-blue-700">{% trans "In Progress" %}</span>
{% elif complaint.status == 'resolved' or complaint.status == 'partially_resolved' %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider bg-green-100 text-green-700">{% trans "Resolved" %}</span>
{% elif complaint.status == 'closed' %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider bg-slate-100 text-slate-600">{% trans "Closed" %}</span>
{% elif complaint.status == 'cancelled' %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider bg-gray-100 text-gray-600">{% trans "Cancelled" %}</span>
{% elif complaint.status == 'contacted' %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider bg-purple-100 text-purple-700">{% trans "Contacted" %}</span>
{% elif complaint.status == 'contacted_no_response' %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider bg-amber-100 text-amber-700">{% trans "No Response" %}</span>
{% else %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider bg-slate-100 text-slate-600">{{ complaint.get_status_display }}</span>
{% endif %}
</td>
<td class="py-3 px-3">
{% if complaint.severity == 'critical' %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider bg-red-100 text-red-700">{% trans "Critical" %}</span>
{% elif complaint.severity == 'high' %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider bg-orange-100 text-orange-700">{% trans "High" %}</span>
{% elif complaint.severity == 'medium' %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider bg-yellow-100 text-yellow-700">{% trans "Medium" %}</span>
{% elif complaint.severity == 'low' %}
<span class="px-2 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wider bg-green-100 text-green-700">{% trans "Low" %}</span>
{% else %}
<span class="text-slate-400">-</span>
{% endif %}
</td>
<td class="py-3 px-3">
<span class="px-2 py-0.5 rounded-lg text-xs font-semibold bg-slate-100 text-slate-700">{{ row.role }}</span>
</td>
<td class="py-3 px-3 text-slate-500 text-xs whitespace-nowrap">{{ complaint.created_at|date:"M d, Y" }}</td>
</tr>
{% endwith %}
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="text-center py-10">
<i data-lucide="inbox" class="w-12 h-12 text-slate-300 mx-auto mb-3"></i>
<p class="text-slate-400 font-medium">{% trans "No complaints found for this staff member" %}</p>
</div>
{% endif %}
</section>
<!-- Staff Activity (PX-Admin / Hospital Admin only) -->
{% if staff.user and user.is_px_admin or user.is_hospital_admin %}
{% if staff_activities %}
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
<div class="flex items-center justify-between mb-6">
<h3 class="font-bold text-navy text-lg flex items-center gap-2">
<i data-lucide="activity" class="w-5 h-5 text-blue"></i>
{% trans "Activity" %}
</h3>
<a href="{% url 'accounts:staff-activity-log' %}?user={{ staff.user.id }}" class="text-sm font-semibold text-blue hover:text-navy transition flex items-center gap-1">
<i data-lucide="external-link" class="w-4 h-4"></i> {% trans "View All" %}
</a>
</div>
<div class="grid grid-cols-3 gap-3 mb-6">
<div class="bg-slate-50 rounded-xl p-3 text-center">
<div class="text-xl font-black text-navy">{{ staff_activities|length }}</div>
<div class="text-[10px] font-bold text-slate uppercase tracking-wider">{% trans "Recent" %}</div>
</div>
<div class="bg-slate-50 rounded-xl p-3 text-center">
<div class="text-xl font-black text-navy">{{ staff_login_count }}</div>
<div class="text-[10px] font-bold text-slate uppercase tracking-wider">{% trans "Logins" %}</div>
</div>
<div class="bg-slate-50 rounded-xl p-3 text-center">
<div class="text-xl font-black text-navy">{{ staff_action_count }}</div>
<div class="text-[10px] font-bold text-slate uppercase tracking-wider">{% trans "Actions" %}</div>
</div>
</div>
<div class="space-y-0 max-h-96 overflow-y-auto">
{% for activity in staff_activities %}
<div class="flex gap-3 py-2.5 {% if not forloop.last %}border-b border-slate-50{% endif %} hover:bg-slate-50 transition rounded-lg px-2">
<div class="flex-shrink-0 mt-0.5">
<div class="w-7 h-7 rounded-lg flex items-center justify-center text-xs
{% if activity.activity_type == 'login' %}bg-green-100 text-green-600
{% elif activity.activity_type == 'logout' %}bg-slate-100 text-slate-500
{% elif activity.activity_type == 'create' %}bg-emerald-100 text-emerald-600
{% elif activity.activity_type == 'update' %}bg-blue-100 text-blue-600
{% elif activity.activity_type == 'delete' %}bg-red-100 text-red-600
{% else %}bg-slate-100 text-slate-600{% endif %}">
{% if activity.activity_type == 'login' %}<i data-lucide="log-in" class="w-3.5 h-3.5"></i>
{% elif activity.activity_type == 'logout' %}<i data-lucide="log-out" class="w-3.5 h-3.5"></i>
{% elif activity.activity_type == 'create' %}<i data-lucide="plus" class="w-3.5 h-3.5"></i>
{% elif activity.activity_type == 'update' %}<i data-lucide="edit" class="w-3.5 h-3.5"></i>
{% elif activity.activity_type == 'delete' %}<i data-lucide="trash" class="w-3.5 h-3.5"></i>
{% else %}<i data-lucide="circle" class="w-3.5 h-3.5"></i>{% endif %}
</div>
</div>
<div class="flex-1 min-w-0">
<div class="flex items-center justify-between gap-2">
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-[10px] font-bold uppercase
{% if activity.activity_type == 'login' or activity.activity_type == 'logout' %}bg-slate-100 text-slate-700
{% elif activity.activity_type == 'create' %}bg-green-100 text-green-700
{% elif activity.activity_type == 'update' %}bg-blue-100 text-blue-700
{% elif activity.activity_type == 'delete' %}bg-red-100 text-red-700
{% else %}bg-slate-100 text-slate-700{% endif %}">
{{ activity.get_activity_type_display }}
</span>
<span class="text-xs text-slate flex-shrink-0">{{ activity.created_at|date:"M d" }} {{ activity.created_at|time:"H:i" }}</span>
</div>
<p class="text-sm text-slate-700 mt-0.5 truncate">{{ activity.description|default:"-" }}</p>
{% if activity.module %}
<span class="text-[10px] font-bold text-slate uppercase">{{ activity.module }}</span>
{% endif %}
{% if activity.ip_address %}
<span class="text-[10px] text-slate ml-2">IP: {{ activity.ip_address }}</span>
{% endif %}
</div>
</div>
{% endfor %}
</div>
</section>
{% endif %}
{% endif %}
</div>
<!-- Right Column (Sidebar) -->
<div class="col-span-4 space-y-6">
<!-- User Account -->
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
<h3 class="font-bold text-navy mb-4 text-sm flex items-center gap-2">
<i data-lucide="user-circle" class="w-4 h-4 text-blue"></i>
{% trans "User Account" %}
</h3>
{% if staff.user %}
<div class="bg-green-50 border border-green-200 rounded-xl p-4 mb-4 flex items-start gap-3">
<i data-lucide="check-circle" class="w-5 h-5 text-green-600 flex-shrink-0 mt-0.5"></i>
<div>
<strong class="text-green-800 block text-sm">{% trans "Account Linked" %}</strong>
<span class="text-green-700 text-xs">{% trans "Staff can log in to the system" %}</span>
</div>
</div>
<ul class="space-y-3 text-sm">
<li class="flex justify-between border-b border-slate-100 pb-2">
<span class="text-slate">{% trans "Username" %}</span>
<span class="font-bold text-navy">{{ staff.user.username }}</span>
</li>
<li class="flex justify-between border-b border-slate-100 pb-2">
<span class="text-slate">{% trans "Active" %}</span>
<span class="font-bold">
{% if staff.user.is_active %}
<span class="px-2 py-0.5 rounded-lg text-xs font-bold bg-green-100 text-green-600">{% trans "Yes" %}</span>
{% else %}
<span class="px-2 py-0.5 rounded-lg text-xs font-bold bg-red-100 text-red-600">{% trans "No" %}</span>
{% endif %}
</span>
</li>
<li class="flex justify-between">
<span class="text-slate">{% trans "Created" %}</span>
<span class="font-bold text-slate-800 text-xs">{{ staff.user.date_joined|date:"M d, Y" }}</span>
</li>
</ul>
{% if user.is_px_admin or user.is_hospital_admin %}
<div class="space-y-2 mt-4 pt-4 border-t border-slate-100">
<button type="button" onclick="sendInvitation()" class="w-full px-4 py-2.5 bg-white border border-slate-200 text-navy rounded-xl font-semibold hover:bg-light transition flex items-center justify-center gap-2 text-sm">
<i data-lucide="mail" class="w-4 h-4"></i> {% trans "Resend Invitation" %}
</button>
<button type="button" onclick="resetPasswordAndResend()" class="w-full px-4 py-2.5 bg-white border border-slate-200 text-blue rounded-xl font-semibold hover:bg-blue-50 transition flex items-center justify-center gap-2 text-sm">
<i data-lucide="key" class="w-4 h-4"></i> {% trans "Reset Password" %}
</button>
<button type="button" onclick="unlinkUserAccount()" class="w-full px-4 py-2.5 bg-white border border-red-200 text-red-600 rounded-xl font-semibold hover:bg-red-50 transition flex items-center justify-center gap-2 text-sm">
<i data-lucide="user-minus" class="w-4 h-4"></i> {% trans "Unlink Account" %}
</button>
</div>
{% endif %}
{% else %}
<div class="bg-amber-50 border border-amber-200 rounded-xl p-4 mb-4 flex items-start gap-3">
<i data-lucide="alert-circle" class="w-5 h-5 text-amber-500 flex-shrink-0 mt-0.5"></i>
<div>
<strong class="text-amber-800 block text-sm">{% trans "No User Account" %}</strong>
<span class="text-amber-700 text-xs">{% trans "Staff cannot log in yet" %}</span>
</div>
</div>
<p class="text-slate text-sm mb-4">
{% trans "Create a user account to allow this staff member to log in to the system." %}
</p>
{% if user.is_px_admin or user.is_hospital_admin or user.is_department_manager and staff.department == user.department %}
{% if staff.email %}
<button type="button" onclick="createUserAccount()" class="w-full px-4 py-3 bg-navy text-white rounded-xl font-semibold hover:bg-blue transition flex items-center justify-center gap-2 text-sm">
<i data-lucide="user-plus" class="w-4 h-4"></i> {% trans "Create User Account" %}
</button>
{% else %}
<div class="bg-slate-50 border border-slate-200 rounded-xl p-3 text-center">
<i data-lucide="info" class="w-4 h-4 text-slate-400 inline mb-1"></i>
<p class="text-slate text-xs">{% trans "Add email address first" %}</p>
</div>
{% endif %}
{% endif %}
{% endif %}
</section>
<!-- System Info -->
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
<h3 class="font-bold text-navy mb-4 text-sm flex items-center gap-2">
<i data-lucide="clock" class="w-4 h-4 text-blue"></i>
{% trans "System Info" %}
</h3>
<ul class="space-y-3 text-sm">
<li class="flex justify-between border-b border-slate-100 pb-2">
<span class="text-slate">{% trans "Status" %}</span>
<span class="font-bold">
{% if staff.status == 'active' %}
<span class="px-2 py-0.5 rounded-lg text-xs font-bold bg-green-100 text-green-600">{% trans "Active" %}</span>
{% else %}
<span class="px-2 py-0.5 rounded-lg text-xs font-bold bg-slate-100 text-slate-500">{% trans "Inactive" %}</span>
{% endif %}
</span>
</li>
<li class="flex justify-between border-b border-slate-100 pb-2">
<span class="text-slate">{% trans "Created" %}</span>
<span class="font-bold text-slate-800 text-xs">{{ staff.created_at|date:"M d, Y" }}</span>
</li>
<li class="flex justify-between">
<span class="text-slate">{% trans "Updated" %}</span>
<span class="font-bold text-slate-800 text-xs">{{ staff.updated_at|date:"M d, Y" }}</span>
</li>
</ul>
</section>
</div>
</div>
<!-- Create User Modal -->
<div class="hidden fixed inset-0 bg-black/50 flex items-center justify-center z-50" id="createUserModal">
<div class="bg-white rounded-2xl shadow-2xl max-w-md w-full mx-4 overflow-hidden">
<div class="bg-navy text-white px-6 py-4 flex justify-between items-center">
<h5 class="font-bold text-lg">{% trans "Create User Account" %}</h5>
<button type="button" class="text-white hover:bg-blue rounded-full p-1 transition" onclick="closeModal('createUserModal')">
<i data-lucide="x" class="w-5 h-5"></i>
</button>
</div>
<div class="p-6">
<p class="text-slate mb-2">{% trans "Create a user account for" %} <strong class="text-navy">{{ staff.get_full_name }}</strong>?</p>
<p class="text-slate text-sm">{% trans "Credentials will be emailed to" %} <strong>{{ staff.email }}</strong>.</p>
</div>
<div class="px-6 py-4 bg-slate-50 flex justify-end gap-3">
<button type="button" class="px-4 py-2 border border-slate-200 text-slate rounded-xl font-semibold hover:bg-white transition" onclick="closeModal('createUserModal')">{% trans "Cancel" %}</button>
<button type="button" class="px-4 py-2 bg-navy text-white rounded-xl font-semibold hover:bg-blue transition" onclick="confirmCreateUser()">{% trans "Create" %}</button>
</div>
</div>
</div>
<!-- Send Invitation Modal -->
<div class="hidden fixed inset-0 bg-black/50 flex items-center justify-center z-50" id="sendInvitationModal">
<div class="bg-white rounded-2xl shadow-2xl max-w-md w-full mx-4 overflow-hidden">
<div class="bg-navy text-white px-6 py-4 flex justify-between items-center">
<h5 class="font-bold text-lg">{% trans "Send Invitation" %}</h5>
<button type="button" class="text-white hover:bg-blue rounded-full p-1 transition" onclick="closeModal('sendInvitationModal')">
<i data-lucide="x" class="w-5 h-5"></i>
</button>
</div>
<div class="p-6">
<p class="text-slate mb-2">{% trans "Send invitation email to" %} <strong class="text-navy">{{ staff.get_full_name }}</strong>?</p>
<p class="text-slate text-sm">{% trans "A new password will be generated and emailed." %}</p>
</div>
<div class="px-6 py-4 bg-slate-50 flex justify-end gap-3">
<button type="button" class="px-4 py-2 border border-slate-200 text-slate rounded-xl font-semibold hover:bg-white transition" onclick="closeModal('sendInvitationModal')">{% trans "Cancel" %}</button>
<button type="button" class="px-4 py-2 bg-navy text-white rounded-xl font-semibold hover:bg-blue transition" onclick="confirmSendInvitation()">{% trans "Send" %}</button>
</div>
</div>
</div>
<!-- Unlink User Modal -->
<div class="hidden fixed inset-0 bg-black/50 flex items-center justify-center z-50" id="unlinkUserModal">
<div class="bg-white rounded-2xl shadow-2xl max-w-md w-full mx-4 overflow-hidden">
<div class="bg-red-500 text-white px-6 py-4 flex justify-between items-center">
<h5 class="font-bold text-lg">{% trans "Unlink User Account" %}</h5>
<button type="button" class="text-white hover:bg-red-600 rounded-full p-1 transition" onclick="closeModal('unlinkUserModal')">
<i data-lucide="x" class="w-5 h-5"></i>
</button>
</div>
<div class="p-6">
<p class="text-slate mb-2">{% trans "Unlink user account from" %} <strong class="text-red-500">{{ staff.get_full_name }}</strong>?</p>
<div class="bg-red-50 border border-red-200 rounded-xl p-3 mt-3">
<p class="text-red-700 text-sm flex items-start gap-2">
<i data-lucide="alert-triangle" class="w-4 h-4 flex-shrink-0 mt-0.5"></i>
{% trans "This will remove login access. The user account will still exist but will no longer be linked to this staff profile." %}
</p>
</div>
</div>
<div class="px-6 py-4 bg-slate-50 flex justify-end gap-3">
<button type="button" class="px-4 py-2 border border-slate-200 text-slate rounded-xl font-semibold hover:bg-white transition" onclick="closeModal('unlinkUserModal')">{% trans "Cancel" %}</button>
<button type="button" class="px-4 py-2 bg-red-500 text-white rounded-xl font-semibold hover:bg-red-600 transition" onclick="confirmUnlinkUser()">{% trans "Unlink" %}</button>
</div>
</div>
</div>
<!-- New Password Display Modal -->
<div class="hidden fixed inset-0 bg-black/50 flex items-center justify-center z-50" id="newPasswordModal">
<div class="bg-white rounded-2xl shadow-2xl max-w-md w-full mx-4 overflow-hidden">
<div class="bg-green-500 text-white px-6 py-4 flex justify-between items-center">
<h5 class="font-bold text-lg flex items-center gap-2">
<i data-lucide="check-circle" class="w-6 h-6"></i> {% trans "Password Reset Successful" %}
</h5>
<button type="button" class="text-white hover:bg-green-600 rounded-full p-1 transition" onclick="closeModal('newPasswordModal')">
<i data-lucide="x" class="w-5 h-5"></i>
</button>
</div>
<div class="p-6">
<div class="bg-green-50 border border-green-200 rounded-xl p-4 mb-4">
<p class="text-green-700 font-semibold flex items-center gap-2">
<i data-lucide="check" class="w-5 h-5"></i>
{% trans "Password reset and email sent successfully!" %}
</p>
</div>
<div class="border-2 border-yellow-300 rounded-xl overflow-hidden">
<div class="bg-yellow-400 text-yellow-900 px-4 py-3 font-bold flex items-center gap-2">
<i data-lucide="key" class="w-5 h-5"></i> {% trans "New Password" %}
</div>
<div class="p-4 bg-white">
<p class="text-slate text-sm mb-3">{% trans "Copy this password:" %}</p>
<div class="flex gap-2">
<input type="text" id="newPasswordDisplay" class="flex-1 px-4 py-3 border border-slate-200 rounded-xl font-bold text-lg text-navy" readonly>
<button type="button" class="px-4 py-3 bg-slate-100 text-slate rounded-xl hover:bg-slate-200 transition" onclick="copyNewPassword()">
<i data-lucide="copy" class="w-5 h-5"></i>
</button>
</div>
</div>
</div>
</div>
<div class="px-6 py-4 bg-slate-50 flex justify-end">
<button type="button" class="px-4 py-2 bg-navy text-white rounded-xl font-semibold hover:bg-blue transition" onclick="closeModal('newPasswordModal')">{% trans "Done" %}</button>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
const CSRF_TOKEN = '{{ csrf_token }}';
function closeModal(modalId) {
document.getElementById(modalId).classList.add('hidden');
}
function showModal(modalId) {
document.getElementById(modalId).classList.remove('hidden');
}
function createUserAccount() {
showModal('createUserModal');
}
function confirmCreateUser() {
const btn = event.target;
btn.disabled = true;
btn.innerHTML = '<i data-lucide="loader-2" class="w-4 h-4 animate-spin inline"></i> {% trans "Creating..." %}';
fetch(`/organizations/api/staff/{{ staff.id }}/create_user_account/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': CSRF_TOKEN
},
body: JSON.stringify({})
})
.then(response => response.json())
.then(data => {
closeModal('createUserModal');
if (data.message) alert(data.message);
location.reload();
})
.catch(error => {
alert('Error: ' + error.message);
btn.disabled = false;
btn.innerHTML = '{% trans "Create" %}';
});
}
function sendInvitation() {
showModal('sendInvitationModal');
}
function confirmSendInvitation() {
const btn = event.target;
btn.disabled = true;
btn.innerHTML = '<i data-lucide="loader-2" class="w-4 h-4 animate-spin inline"></i> {% trans "Sending..." %}';
fetch(`/organizations/api/staff/{{ staff.id }}/send_invitation/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': CSRF_TOKEN
},
body: JSON.stringify({})
})
.then(response => response.json())
.then(data => {
closeModal('sendInvitationModal');
if (data.message) alert(data.message);
location.reload();
})
.catch(error => {
alert('Error: ' + error.message);
btn.disabled = false;
btn.innerHTML = '{% trans "Send" %}';
});
}
function unlinkUserAccount() {
showModal('unlinkUserModal');
}
function confirmUnlinkUser() {
const btn = event.target;
btn.disabled = true;
btn.innerHTML = '<i data-lucide="loader-2" class="w-4 h-4 animate-spin inline"></i> {% trans "Unlinking..." %}';
fetch(`/organizations/api/staff/{{ staff.id }}/unlink_user/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': CSRF_TOKEN
},
body: JSON.stringify({})
})
.then(response => response.json())
.then(data => {
closeModal('unlinkUserModal');
if (data.message) alert(data.message);
location.reload();
})
.catch(error => {
alert('Error: ' + error.message);
btn.disabled = false;
btn.innerHTML = '{% trans "Unlink" %}';
});
}
function resetPasswordAndResend() {
if (!confirm('{% trans "Reset password and resend credentials?" %}')) {
return;
}
fetch(`/organizations/api/staff/{{ staff.id }}/reset_password_and_resend/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': CSRF_TOKEN
},
body: JSON.stringify({})
})
.then(response => response.json())
.then(data => {
if (data.success && data.new_password) {
document.getElementById('newPasswordDisplay').value = data.new_password;
showModal('newPasswordModal');
} else if (data.error) {
alert('Error: ' + data.error);
}
})
.catch(error => {
alert('Error: ' + error.message);
});
}
function copyNewPassword() {
const passwordInput = document.getElementById('newPasswordDisplay');
passwordInput.select();
passwordInput.setSelectionRange(0, 99999);
try {
navigator.clipboard.writeText(passwordInput.value).then(function() {
const btn = event.target.closest('button');
const originalHTML = btn.innerHTML;
btn.innerHTML = '<i data-lucide="check" class="w-5 h-5"></i>';
setTimeout(() => {
btn.innerHTML = originalHTML;
lucide.createIcons();
}, 1500);
});
} catch (err) {
document.execCommand('copy');
alert('{% trans "Password copied!" %}');
}
}
// Initialize Lucide icons
document.addEventListener('DOMContentLoaded', function() {
lucide.createIcons();
});
</script>
{% endblock %}