241 lines
14 KiB
HTML
241 lines
14 KiB
HTML
{% load i18n %}
|
|
<div id="inquiryQuickModal" class="fixed inset-0 bg-black/50 z-50 hidden flex items-center justify-center p-4 backdrop-blur-sm">
|
|
<div class="bg-white rounded-2xl shadow-2xl w-full max-w-lg max-h-[90vh] overflow-y-auto">
|
|
<div class="p-6 border-b border-slate-200">
|
|
<div class="flex items-center justify-between">
|
|
<h3 class="text-xl font-bold text-navy flex items-center gap-2">
|
|
<i data-lucide="zap" class="w-5 h-5 text-amber-500"></i>
|
|
{% trans "New Inquiry" %}
|
|
</h3>
|
|
<button type="button" onclick="closeInquiryQuickModal()" class="text-slate-400 hover:text-slate-600 transition">
|
|
<i data-lucide="x" class="w-5 h-5"></i>
|
|
</button>
|
|
</div>
|
|
<p class="text-sm text-slate mt-2">
|
|
{% trans "Capture the caller's details. The inquiry is auto-activated and assigned to you; AI fills the subject and priority in the background." %}
|
|
</p>
|
|
</div>
|
|
|
|
<form id="inquiryQuickForm" onsubmit="handleInquiryQuickSubmit(event)">
|
|
{% csrf_token %}
|
|
<div class="p-6 space-y-4">
|
|
<div>
|
|
<label class="block text-sm font-semibold text-navy mb-2" for="iqMessage">{% trans "Message" %} <span class="text-red-500">*</span></label>
|
|
<textarea id="iqMessage" name="message" rows="4" required
|
|
class="w-full px-4 py-3 border-2 border-slate-200 rounded-xl focus:outline-none focus:border-navy focus:ring-2 focus:ring-navy/20 resize-none text-sm"
|
|
placeholder="{% trans 'What is the inquiry about?' %}"></textarea>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-semibold text-navy mb-2" for="iqContactName">{% trans "Contact Name" %} <span class="text-red-500">*</span></label>
|
|
<input id="iqContactName" name="contact_name" type="text" required
|
|
class="w-full px-4 py-3 border-2 border-slate-200 rounded-xl focus:outline-none focus:border-navy focus:ring-2 focus:ring-navy/20 text-sm"
|
|
placeholder="{% trans 'Full name' %}">
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm font-semibold text-navy mb-2" for="iqContactPhone">{% trans "Contact Phone" %} <span class="text-red-500">*</span></label>
|
|
<input id="iqContactPhone" name="contact_phone" type="tel" required
|
|
pattern="(\+?966|0)?5[0-9]{8}" inputmode="tel"
|
|
class="w-full px-4 py-3 border-2 border-slate-200 rounded-xl focus:outline-none focus:border-navy focus:ring-2 focus:ring-navy/20 text-sm"
|
|
placeholder="{% trans '05XXXXXXXX or +9665XXXXXXXX' %}">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-semibold text-navy mb-2" for="iqContactEmail">{% trans "Contact Email" %}</label>
|
|
<input id="iqContactEmail" name="contact_email" type="email"
|
|
class="w-full px-4 py-3 border-2 border-slate-200 rounded-xl focus:outline-none focus:border-navy focus:ring-2 focus:ring-navy/20 text-sm"
|
|
placeholder="{% trans 'Email (optional)' %}">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm font-semibold text-navy mb-2" for="iqLocationType">{% trans "Location Type" %} <span class="text-red-500">*</span></label>
|
|
<select id="iqLocationType" name="location_type" required
|
|
class="w-full px-4 py-3 border-2 border-slate-200 rounded-xl focus:outline-none focus:border-navy focus:ring-2 focus:ring-navy/20 text-sm bg-white">
|
|
<option value="">{% trans "Select location type" %}</option>
|
|
<option value="OP">{% trans "Outpatient" %}</option>
|
|
<option value="IP">{% trans "Inpatient" %}</option>
|
|
<option value="ER">{% trans "Emergency" %}</option>
|
|
<option value="GENERAL">{% trans "General" %}</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-semibold text-navy mb-2" for="iqDeptCategory">{% trans "Department Category" %} <span class="text-red-500">*</span></label>
|
|
<select id="iqDeptCategory" required onchange="loadQuickInquiryDepartments(this.value)"
|
|
class="w-full px-4 py-3 border-2 border-slate-200 rounded-xl focus:outline-none focus:border-navy focus:ring-2 focus:ring-navy/20 text-sm bg-white">
|
|
<option value="">{% trans "Select category" %}</option>
|
|
<option value="medical">{% trans "Medical" %}</option>
|
|
<option value="non_medical">{% trans "Non-Medical" %}</option>
|
|
<option value="nursing">{% trans "Nursing" %}</option>
|
|
<option value="support_services">{% trans "Support Services" %}</option>
|
|
<option value="administrative">{% trans "Administrative" %}</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm font-semibold text-navy mb-2" for="iqDepartment">{% trans "Department" %} <span class="text-red-500">*</span></label>
|
|
<select id="iqDepartment" name="department" required onchange="loadQuickInquirySections(this.value)"
|
|
class="w-full px-4 py-3 border-2 border-slate-200 rounded-xl focus:outline-none focus:border-navy focus:ring-2 focus:ring-navy/20 text-sm bg-white">
|
|
<option value="">{% trans "Select category first" %}</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-semibold text-navy mb-2" for="iqSection">{% trans "Section" %} <span class="text-slate-400 font-normal">({% trans "optional" %})</span></label>
|
|
<select id="iqSection" name="section"
|
|
class="w-full px-4 py-3 border-2 border-slate-200 rounded-xl focus:outline-none focus:border-navy focus:ring-2 focus:ring-navy/20 text-sm bg-white">
|
|
<option value="">{% trans "Select department first" %}</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="inquiryQuickError" class="hidden text-sm text-red-600 bg-red-50 border border-red-200 p-3 rounded-lg"></div>
|
|
</div>
|
|
|
|
<div class="p-6 border-t border-slate-200 flex gap-3">
|
|
<button type="submit" id="inquiryQuickSubmitBtn"
|
|
class="flex-1 px-4 py-2.5 bg-navy text-white rounded-xl font-semibold hover:bg-navy/90 transition text-sm inline-flex items-center justify-center gap-2">
|
|
<i data-lucide="plus" class="w-4 h-4"></i>
|
|
{% trans "Create & Activate" %}
|
|
</button>
|
|
<button type="button" onclick="closeInquiryQuickModal()"
|
|
class="px-4 py-2.5 bg-white border-2 border-slate-200 rounded-xl font-semibold text-slate-600 hover:bg-slate-50 transition text-sm">
|
|
{% trans "Cancel" %}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function openInquiryQuickModal() {
|
|
var modal = document.getElementById('inquiryQuickModal');
|
|
if (!modal) return;
|
|
var form = document.getElementById('inquiryQuickForm');
|
|
if (form) form.reset();
|
|
document.getElementById('inquiryQuickError').classList.add('hidden');
|
|
// Reset the dependent dropdowns to their placeholders
|
|
var deptSelect = document.getElementById('iqDepartment');
|
|
if (deptSelect) deptSelect.innerHTML = '<option value="">{% trans "Select category first" %}</option>';
|
|
var sectionSelect = document.getElementById('iqSection');
|
|
if (sectionSelect) sectionSelect.innerHTML = '<option value="">{% trans "Select department first" %}</option>';
|
|
modal.classList.remove('hidden');
|
|
if (typeof lucide !== 'undefined') lucide.createIcons();
|
|
setTimeout(function () {
|
|
var m = document.getElementById('iqMessage');
|
|
if (m) m.focus();
|
|
}, 50);
|
|
}
|
|
|
|
function loadQuickInquiryDepartments(deptCategory) {
|
|
var deptSelect = document.getElementById('iqDepartment');
|
|
var sectionSelect = document.getElementById('iqSection');
|
|
if (sectionSelect) sectionSelect.innerHTML = '<option value="">{% trans "Select department first" %}</option>';
|
|
if (!deptSelect) return;
|
|
deptSelect.innerHTML = '<option value="">{% trans "Select category first" %}</option>';
|
|
if (!deptCategory) return;
|
|
var hospitalId = '{{ request.tenant_hospital.id|default:"" }}';
|
|
deptSelect.innerHTML = '<option value="">{% trans "Loading..." %}</option>';
|
|
var url = '/organizations/dropdowns/departments-by-category/?category=' + encodeURIComponent(deptCategory);
|
|
if (hospitalId) url += '&hospital=' + encodeURIComponent(hospitalId);
|
|
fetch(url)
|
|
.then(function (r) { return r.json(); })
|
|
.then(function (data) {
|
|
deptSelect.innerHTML = '<option value="">{% trans "Select department" %}</option>';
|
|
(data || []).forEach(function (d) {
|
|
var opt = document.createElement('option');
|
|
opt.value = d.id;
|
|
opt.textContent = d.name_en || d.name;
|
|
deptSelect.appendChild(opt);
|
|
});
|
|
if (data && data.length === 0) {
|
|
deptSelect.innerHTML = '<option value="">{% trans "No departments for this category" %}</option>';
|
|
}
|
|
})
|
|
.catch(function () {
|
|
deptSelect.innerHTML = '<option value="">{% trans "Error loading departments" %}</option>';
|
|
});
|
|
}
|
|
|
|
function loadQuickInquirySections(deptId) {
|
|
var sectionSelect = document.getElementById('iqSection');
|
|
if (!sectionSelect) return;
|
|
sectionSelect.innerHTML = '<option value="">{% trans "Select department first" %}</option>';
|
|
if (!deptId) return;
|
|
sectionSelect.innerHTML = '<option value="">{% trans "Loading..." %}</option>';
|
|
fetch('/organizations/dropdowns/sections/' + encodeURIComponent(deptId) + '/')
|
|
.then(function (r) { return r.json(); })
|
|
.then(function (data) {
|
|
sectionSelect.innerHTML = '<option value="">{% trans "Select section" %}</option>';
|
|
(data || []).forEach(function (s) {
|
|
var opt = document.createElement('option');
|
|
opt.value = s.id;
|
|
opt.textContent = s.name_en || s.name;
|
|
sectionSelect.appendChild(opt);
|
|
});
|
|
if (!sectionSelect.options.length || (sectionSelect.options.length === 1 && !sectionSelect.options[0].value)) {
|
|
sectionSelect.innerHTML = '<option value="">{% trans "No sections for this department" %}</option>';
|
|
}
|
|
})
|
|
.catch(function () {
|
|
sectionSelect.innerHTML = '<option value="">{% trans "Error loading sections" %}</option>';
|
|
});
|
|
}
|
|
|
|
function closeInquiryQuickModal() {
|
|
var modal = document.getElementById('inquiryQuickModal');
|
|
if (modal) modal.classList.add('hidden');
|
|
}
|
|
|
|
function handleInquiryQuickSubmit(event) {
|
|
event.preventDefault();
|
|
var form = event.target;
|
|
var errorDiv = document.getElementById('inquiryQuickError');
|
|
var submitBtn = document.getElementById('inquiryQuickSubmitBtn');
|
|
var formData = new FormData(form);
|
|
|
|
errorDiv.classList.add('hidden');
|
|
submitBtn.disabled = true;
|
|
submitBtn.innerHTML = '<span class="inline-block w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin mr-2"></span>{% trans "Creating..." %}';
|
|
|
|
fetch('{% url "inquiries:inquiry_quick_create" %}', {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest',
|
|
'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]') ? document.querySelector('[name=csrfmiddlewaretoken]').value : ''
|
|
}
|
|
})
|
|
.then(async function (response) {
|
|
var data = null;
|
|
try { data = await response.json(); } catch (e) { /* non-JSON */ }
|
|
if (data && data.success === true) return data;
|
|
throw new Error(
|
|
(data && data.error)
|
|
|| (response.ok ? '{% trans "Failed to create inquiry." %}' : '{% trans "Server error" %} (' + response.status + ')')
|
|
);
|
|
})
|
|
.then(function () {
|
|
closeInquiryQuickModal();
|
|
window.location.reload();
|
|
})
|
|
.catch(function (error) {
|
|
errorDiv.textContent = error.message;
|
|
errorDiv.classList.remove('hidden');
|
|
submitBtn.disabled = false;
|
|
submitBtn.innerHTML = '<i data-lucide="plus" class="w-4 h-4"></i> {% trans "Create & Activate" %}';
|
|
if (typeof lucide !== 'undefined') lucide.createIcons();
|
|
});
|
|
}
|
|
|
|
document.addEventListener('keydown', function (e) {
|
|
if (e.key === 'Escape') {
|
|
var modal = document.getElementById('inquiryQuickModal');
|
|
if (modal && !modal.classList.contains('hidden')) closeInquiryQuickModal();
|
|
}
|
|
});
|
|
</script>
|