558 lines
28 KiB
HTML
558 lines
28 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.first_name|first }}{{ staff.last_name|first }}
|
|
</div>
|
|
<div>
|
|
<h1 class="text-2xl font-bold text-navy">{{ staff.get_full_name }}</h1>
|
|
<p class="text-slate text-sm">{{ staff.job_title|default:"-" }} <span class="text-slate-300">|</span> {{ staff.get_staff_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>
|
|
<label class="text-xs font-bold text-slate uppercase block mb-1">{% trans "Subsection" %}</label>
|
|
<div class="font-bold text-slate-800">{{ staff.subsection|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>
|
|
</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 %}
|
|
{% 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>
|
|
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': getCookie('csrftoken')
|
|
},
|
|
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': getCookie('csrftoken')
|
|
},
|
|
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': getCookie('csrftoken')
|
|
},
|
|
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': getCookie('csrftoken')
|
|
},
|
|
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 %}
|